State Pattern in Java (with Example)
The State pattern explained: an object changes behaviour as its internal state changes by delegating to a state object, with each state its own class driving transitions — the clean way to build a state machine. State vs Strategy, code, UML.
🟠Design Patterns · Behavioral · Senior
The State pattern lets an object change its behaviour when its internal state changes — as if it switched to a different class. A vending machine acts completely differently when it has no coin vs when a coin is inserted vs when it's dispensing. Instead of tangling all that into giant conditionals, State gives each state its own class. It's the clean way to model anything that behaves like a state machine.
The problem: state conditionals everywhere
Model a vending machine. Without a pattern, every method is a maze of state checks:
void insertCoin() {
if (state == NO_COIN) { state = HAS_COIN; }
else if (state == HAS_COIN){ /* already have a coin */ }
else if (state == SOLD) { /* wait, dispensing */ }
// …and every OTHER method repeats this same switch
}
Each action duplicates the same state switch, the transitions are scattered and hard to follow, and adding a state means editing every method. It's fragile and unreadable.
The solution: one class per state
🟠Define a State interface with the machine's actions; each concrete state implements them and decides the next state; the context delegates to its current state:
interface State { void insertCoin(); void pressButton(); }
class NoCoinState implements State {
private final Machine m;
NoCoinState(Machine m){ this.m = m; }
public void insertCoin(){ m.setState(m.hasCoin); } // transition!
public void pressButton(){ System.out.println("Insert a coin first"); }
}
class HasCoinState implements State {
private final Machine m;
HasCoinState(Machine m){ this.m = m; }
public void insertCoin(){ System.out.println("Coin already inserted"); }
public void pressButton(){ m.dispense(); m.setState(m.noCoin); }
}
class Machine { // the context
State noCoin = new NoCoinState(this), hasCoin = new HasCoinState(this);
private State state = noCoin;
void setState(State s){ this.state = s; }
void insertCoin(){ state.insertCoin(); } // delegate to current state
void pressButton(){ state.pressButton(); }
}
Now each state's rules live in one focused class, transitions are explicit (a state sets the next state), and adding a "Sold Out" state is a new class — no editing the others. The machine just delegates to whatever state it's in.
State vs Strategy (the classic question)
🟠They're structurally identical — a context delegating to an interface — so interviewers love to ask the difference. It's intent and who drives the change: with Strategy, the client picks an algorithm and it stays put; with State, the object transitions itself between states as events occur, and states know about each other. Strategy = interchangeable algorithms chosen outside; State = a self-driving state machine.
Where you see it
Anything shaped like a state machine: order lifecycle (placed → paid → shipped → delivered), a media player (playing/paused/stopped), a TCP connection, document workflow (draft → review → published), UI wizards, game character states. If you're drawing a state diagram, State is the pattern to implement it.
When to use it
Use State when an object's behaviour depends heavily on its state and you have sprawling conditionals switching on that state, especially with well-defined transitions. If there are only two trivial states and little behaviour, a simple boolean/enum may be enough — don't over-model.
The interview-ready summary
"State lets an object change behaviour as its internal state changes by delegating to a state object; each state is its own class implementing the same interface, and states drive the transitions to one another. It replaces giant state-switch conditionals scattered across methods, keeping each state's rules in one place and making new states additive. It looks like Strategy, but here the object transitions itself rather than the client choosing. Perfect for order lifecycles, media players, and vending machines." That's State plus the must-know Strategy contrast."
What to read next
- Command Pattern — wrapping requests as objects
- Strategy Pattern — State's structural twin
- All Design Patterns (hub)
- ← The complete System Design guide (hub)