Every commerce backend has an Order class, and every Order class has a String status. It starts as three values and one method. Then the lifecycle grows: CREATED, PAID, SHIPPED, DELIVERED, CANCELLED. And every method — pay(), ship(), cancel(), refund(), deliver() — grows its own switch(status) to decide what’s allowed from here.
The bug is never in the switch you’re looking at. It’s in the one you forgot. Someone adds a RETURNED status for a new returns flow, updates refund() and deliver(), and misses the arm in cancel(). Now a returned order can be cancelled, which double-refunds the customer. The rule “a shipped order cannot be cancelled” was never written down in one place — it was scattered across five methods, so no single edit could keep it true.
The problem isn’t the number of states. It’s that the behavior for a mode and the legal transitions out of that mode are smeared across every method instead of living together. The Gang of Four named the fix.
The intuition: a traffic light knows what comes next
A traffic light isn’t a controller holding a color variable and a big switch(color). Think of it as three objects. Green knows one thing: after its interval, hand control to Yellow. Yellow knows: next is Red. Red knows: next is Green. No single “light manager” enumerates the whole cycle — each color owns its own behavior and the single arrow out of it.
That’s the whole pattern. The light is the context — it just holds “the current color” and delegates. Each color is a state — and crucially, a state can promote the context to the next state. Green doesn’t ask permission to become Yellow; it makes it happen.
The members-only continuation takes it from intuition to running code: the switch(status) smell shown in full, the context/contract/self-promoting-state implementation, a class-diagram walkthrough of the finite-state machine, an order traced through its whole lifecycle, the State-vs-Strategy tell, the tradeoffs, a vending-machine refactor challenge, and the interview corner.
Keep reading with Premium
You've reached the members-only part of this deep-dive — the full implementation, the interactive ring simulator, and the step-by-step walkthrough. Unlock it with a membership.
Discussion
Loading the conversation…
Discussion
Loading the conversation…