State Pattern

What is the State pattern?

State means: an object changes its behavior when its internal state changes, by moving each mode’s logic into its own small class.

From the outside it can look like the object changed class. What an action does is no longer decided by a big switch inside one method — it is decided by whichever state object is currently active.

Three pieces work together:

  1. Context — the object callers talk to (Order, VendingMachine).
  2. State interface — the actions that depend on mode (pay, ship).
  3. Concrete states — one class per mode, each implementing those actions its own way.

The context holds the current state and delegates every action to it. When a transition happens, a different state object gets swapped in.


The problem it solves

A first draft of order status logic often looks like this:

Every new status multiplies branches. Every action method repeats similar checks, and invalid transitions are easy to miss. State moves each mode’s rules into its own class, so pay() in Draft never shares a method body with pay() in Shipped.


The state interface and context


The concrete states

Usage reads like a story:

Invalid moves fail in the state that knows they are invalid — not in a shared swamp of conditionals.


A vending-machine sketch

A classic teaching example is a machine with modes like “no coin,” “has coin,” and “sold.” The context exposes insertCoin(), selectProduct(), and dispense(). Each state implements those methods differently:

  • In no coin, insertCoin moves to has-coin; dispense refuses.
  • In has coin, selectProduct moves toward sold; another coin might be rejected or queued.
  • In sold, dispense finishes the sale and returns to no-coin (or “sold out”).

You do not need to memorize every transition. The lesson is the structure: context delegates, states decide, transitions replace the state object.


State vs Strategy

Both patterns look similar: a context holds a helper object and delegates. The intent differs.

Strategy picks an algorithm. The context usually does not change strategy by itself after every call — the caller chooses.

State models a life cycle. Actions cause transitions. The next behavior depends on where you are in that cycle.

If you are swapping formulas, think Strategy. If you are modeling modes and allowed moves, think State.


When it helps

Use State when behavior changes sharply by mode, transition rules are getting hard to follow in one class, or you want invalid moves to be obvious in one place per mode.

It is especially helpful when new states are likely — adding a Refunded mode should not require editing every method in a large context class.


When it hurts

If you only have two booleans and three ifs, State is heavier than the problem. Do not build a framework of state classes for a toggle.

Also avoid putting unrelated business logic into state classes until they become a second god-object. States should own mode behavior and transitions, not your whole domain model.


Practical tips

  • Name states after domain language (Draft, Paid, Shipped), not implementation tricks.
  • Keep the context’s API stable; let states vary underneath.
  • Decide who triggers transitions — usually the state methods call back into the context.
  • Document the legal transitions, even with a small comment diagram.
  • Prefer failing loudly on illegal actions during development; silent no-ops hide bugs.

Check your understanding

State in one line?
Each mode’s behavior lives in its own class, swapped as the object’s life cycle moves.

What does the context do?
It holds the current state and forwards actions to it.

Why not just use a status string and switches?
Switches grow with every state and action; State localizes each mode’s rules.

How is it different from Strategy?
Strategy selects an algorithm. State models transitions between modes.


What to learn next

Next: Template Method Pattern — a base class fixes the steps of an algorithm while subclasses fill in the parts that vary.