Menu

Earn Premium with Referrals

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

See how it works and start inviting friends.

Spaghetti Code
LLD

Spaghetti Code

Learn how tangled control flow, excessive coupling, and poor structure make code difficult to understand and change.

The Original Sin

The term predates objects: 1960s assembly and early BASIC programs where GOTO jumped anywhere, producing flowcharts that looked like — and were called — spaghetti. Dijkstra’s Go To Statement Considered Harmful (1968) triggered structured programming: code should be expressible as sequence, selection, iteration — constructs with single entry and exit points, so control flow stays readable top-to-bottom.

 STRUCTURED (readable)                SPAGHETTI (anywhere-jumps)

 start                                start
   │                                    │◄──────┐
   ▼                                  A ─┼─► B    │
 if (valid)                            │  ▲     │
   process();      one entry,         C ◄─┘ jump  │
 else                    one exit      │    back  │
   reject();            per block     ▼          │
 next_step()                          GOTO ...───┘
   ▼                                  (trace requires a pencil)
 end

Modern Forms (no goto required)

Java removed goto decades ago; the shape survives:

Modern formSpaghetti equivalence
Deeply nested ifs (6+ levels)Flow buried in indentation
Boolean flags threaded through methods (done, error, retry)Data-flow spaghetti — state mutated across call levels
Exception-driven control (try/catch as normal branching)Jumps hidden inside throw/catch
Callback pyramids / promise chains gone wildAsynchronous goto
God methods calling each other cyclicallyInter-procedural tangle

The shared symptom: to understand any line you must hold the whole file’s execution history in your head.

The Cost Mechanism

  • Change amplification: fixing one branch perturbs others sharing hidden flag state.
  • Test impossibility: no seams; every test exercises the entire tangle.
  • Onboarding cliff: new engineers trace flows manually for weeks.
  • The “shotgun surgery” smell is spaghetti’s sibling at class level.

The Cure

 1. Guard clauses        → flatten nesting: return early on invalid input
 2. Extract Method       → each phase gets a name; depth collapses
 3. Kill flag arguments  → split the method instead of branching on booleans
 4. Exceptions for       → exceptional paths only; never routine flow
    exceptional cases
 5. State machines for   → complex status transitions become explicit,
    workflow logic          enumerable states instead of scattered flags

Guard clauses alone fix most cases:

// before: nested pyramid              // after: flat guards
if (order != null) {                  if (order == null) return;
  if (order.isValid()) {              if (!order.isValid()) return badRequest();
    if (stock > 0) {                  if (stock <= 0) return outOfStock();
      charge();                       charge();
    }                                 return ok();
  }
}

Interview Framing

Shown tangled logic, the expected move is naming the structural fix (guards + extraction + explicit state machine) rather than line-level polish — refactoring control flow is an LLD skill, not formatting.

My Private Notes

Notes are auto-saved locally to this device.