State
State lets an object change behavior as its internal condition changes by delegating to state-specific objects. It replaces status-driven conditionals with an explicit object-based state machine where each state owns its transitions.
State is a behavioral pattern that allows an object to change its behavior when its internal state changes, so it appears as though the object changed its class. It replaces large conditional statements that branch on a status field with a set of state classes, each encapsulating the behavior valid in that state. The object delegates behavior to its current state object.
How It Works
A context holds a reference to a state object representing its current condition. The state interface declares the operations whose behavior depends on state. Each concrete state implements those operations for one condition and decides which state should come next, either returning a new state to the context or asking the context to transition. When the context receives a request, it forwards it to the current state, whose implementation runs and may trigger a transition.
Transitions become explicit and localized: each state knows its valid successors. This turns an implicit, conditional-driven state machine into an object graph that mirrors a state diagram.
When to Use It
Use State when an object's behavior depends heavily on its state and it must change behavior at runtime, or when methods contain large conditionals that select behavior based on the object's current status. It models order lifecycles, connection handling, document workflows, media players, and protocol handshakes cleanly.
Trade-offs
The pattern introduces a class per state, which is overkill for objects with only two or three states or rare transitions. Transition logic can be spread across many state classes, making the overall machine harder to view at a glance; a transition table or diagram helps. Sharing data across states requires passing it through the context. Despite this, State greatly improves clarity when the number of states and rules grows.
Related Patterns
Strategy has the same structure but different intent: Strategy's algorithm is chosen by the client, while State transitions are driven by the object itself. Memento can save and restore a context's state object. Observer can notify others when transitions occur. Flyweight is sometimes used to share stateless state objects across many contexts. At larger scale the same thinking appears as explicit finite state machines, workflow engines, and the saga pattern, which coordinates a long-running business process as a sequence of states and compensating transitions across services.
Example
A document has Draft, Review, and Published states. In Draft, publish moves to Review; in Review, approve moves to Published and reject returns to Draft; in Published, edits are rejected outright. Each rule lives in its own state class, and the document simply delegates whatever request it receives to its current state. Adding an Archived state means adding one class and wiring its transitions, with no sprawling conditionals to untangle. The pattern models many real systems cleanly: a TCP connection moving through listen, established, and closed; a media player toggling between stopped, playing, and paused; an order progressing from placed to shipped to delivered. Because each transition is explicit and local to a state, the resulting object graph reads like the state diagram it implements, which makes the rules auditable and the illegal transitions impossible by construction.