Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Code Smells
LLD

Code Smells

Identify common indicators of problematic design and code that may lead to maintenance difficulties.

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:

SmellLegitimate exception
Switch statementsExhaustive dispatch over sealed types / parser token kinds
Long methodPerformance-critical inner loop with measured justification
Middle manFacades and proxies are intentional forwarding layers
Primitive obsessionBoundary-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.

My Private Notes

Notes are auto-saved locally to this device.