What a Smell Is
A code smell is not a bug — tests pass, users are served. It is surface evidence of deeper design decay, the way smoke indicates fire without being it. Smells matter in LLD interviews because refactoring questions are answered by naming the smell, then applying its known cure. The two largest families:
- Bloaters — code that has grown too big to reason about.
- Couplers — code whose classes know too much about each other.
Bloaters
┌──────────────────────────────────────────────┐
│ LongMethod (100+ lines) │ smell: one method does
│ parse → validate → compute → persist → log │ five jobs; loops + flags
│ if (flag) { ...40 lines... } │ entangle them
└──────────────────────────────────────────────┘ cure: Extract Method per phase
LargeClass — 30+ fields, dozens of methods doing pricing AND persistence AND reporting.
Multiple reasons to change = SRP violation at class scale.
cure: Extract Class around cohesive field/method clusters.
PrimitiveObsession — domain concepts modeled as bare String/int:
order status as "SHIPPED"/"shipped"/"S" scattered everywhere.
cure: value types/enums; validation moves into the type once.
DataClumps — the same (firstName, lastName, email, phone) tuple passed through
five signatures. The clump IS a missing class. cure: Introduce Parameter Object.
LongParameterList — 6+ params, callers passing null, null, false...
cure: parameter object or builder for construction-heavy cases.
Couplers
FeatureEnvy InappropriateIntimacy
A method of Order spends its Two classes reach into each other's
life reading Customer fields: internals via getters both directions.
customer.getZip() cure: Move Method/Field to put
customer.getRegion() behavior where the data lives;
customer.getTaxRate() or merge them if separation buys nothing.
→ the method wants to LIVE in
Customer. cure: Move Method.
MessageChains MiddleMan
order.getCustomer() Delegator whose every method just
.getAddress() forwards: invoice.getCustomer().getName()
.getCountry() cure: Remove Middle Man — expose
.getCode() the delegate directly, or keep only
→ coupled to the whole chain's when guarding something real.
structure; any link change
breaks callers.
cure: Hide Delegate — tell the
first object what you need.
Why Smells Beat Rulebooks
Refactoring catalogs (Fowler) map smell→cure mechanically, which makes reviews teachable: instead of “I don’t like this,” a reviewer says “data clump — introduce a parameter object.” Teams align faster on named diagnoses than on taste.
Judgment Calls
Smells are heuristics with false positives:
| Smell | Legitimate exception |
|---|---|
| Switch statements | Exhaustive dispatch over sealed types / parser token kinds |
| Long method | Performance-critical inner loop with measured justification |
| Middle man | Facades and proxies are intentional forwarding layers |
| Primitive obsession | Boundary-layer DTOs mirroring wire formats |
The skill is noticing the smell, then deciding whether the context earns the exemption — reflexively refactoring everything is its own anti-pattern.
Interview Framing
Asked “how would you improve this code?”: name smells precisely, propose the matching refactor, and state which smells you would deliberately leave — that last sentence separates senior answers from checklist recitation.
Premium Content
Unlock Code Smells and all premium lessons with a subscription.
From ₹199.99/year — See plans