| name | apply-state-pattern |
| description | Use when an object's behavior changes based on its internal state and the logic for each state is complex — replacing large conditional chains with state objects where each state encapsulates its own behavior. |
Apply State Pattern
Allow an object to alter its behavior when its internal state changes — by delegating behavior to state objects rather than using conditional logic.
Why This Is Best Practice
Adopted by: XState (JavaScript statechart library — 1.5M weekly npm downloads)
implements State pattern as its core model. TCP protocol stack implements state as
objects (CLOSED, LISTEN, SYN_SENT, ESTABLISHED, etc. — each with its own behavior for
each operation). Unity's Animator Controller is a visual state machine based on the
same pattern. Every parser generator (ANTLR, PLY) produces state-based recognizers.
Impact: GoF documents that without the State pattern, a class with 4 states and
6 operations has 4×6=24 conditional branches scattered across all methods. The State
pattern consolidates each state's behavior into one class — 4 state classes of 6 methods
each. Adding a 5th state requires one new class, not editing 6 existing methods.
Why best: if/elif state dispatch — the alternative — scatters state logic across
every method, making it hard to add states or understand what happens in a given state.
State objects make each state's behavior cohesive, isolated, and independently testable.
Sources: Gamma et al. (1994) pp. 305–313; XState documentation; RFC 793 (TCP state machine)
Steps
Step 1: Define the state interface with all state-dependent methods
from abc import ABC, abstractmethod
class OrderState(ABC):
@abstractmethod
def () -> : ...
() -> : ...
() -> : ...