Catalog / Behavioral Patterns / State Pattern
BEHAVIORAL

State Pattern

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

Intent & Objective

Extract state-related behaviors into separate state classes. The original object delegates state-dependent work to an instance of a concrete state class instead of implementing massive conditional branches.

πŸ‘₯ Real-World Human Analogies & Social Roles
4 Intuitive Scenarios
Traffic Light Urban Traffic Control

"Behavior changes automatically depending on current state (Red: Stop, Yellow: Prepare, Green: Go)."

Human Mood Swings Emotional Psychology

"A person reacts very differently to the same situation depending on whether they are calm, joyful, or furious."

ATM Machine Operation Banking Hardware

"Available buttons and actions change dynamically based on whether a card is inserted, PIN is verified, or cash is dispensing."

Kanban Task Board Developer Daily Life

"A user story card changes rules and assignee as it moves from To Do -> In Progress -> Code Review -> Done."

The Problem

State machines written with giant `switch (state)` statements in every method. As new states are introduced, every single method in the class must be altered, causing regression bugs.

The Solution

Create new classes for all possible states of an object and extract all state-specific behaviors into these classes. Change the active state object at runtime.

Key Participants & Architectural Roles

Context
Stores a reference to one of the concrete state objects and delegates state-specific work
State Interface
Declares methods common to all concrete states
Concrete States
Provide their own implementations for context methods and transition context state

Code Samples (Traditional OOP vs Functional Programming)

Available in C++, Python, and Java

Paradigm Contrast: Traditional OOP vs Functional / Data-Oriented

In OOP, State is modeled via polymorphic classes mutating a context pointer. In Functional Programming, State is modeled as a Finite State Machine using Discriminated Unions / Algebraic Data Types, pure state transitions `(State, Event) -> State`, and Reducers (like Redux).

Advantages

  • βœ“ Single Responsibility Principle: organizes the code related to particular states into separate classes
  • βœ“ Open/Closed Principle: introduces new states without changing existing state classes or context
  • βœ“ Eliminates bulky switch/case state machine conditionals

Trade-offs

  • βœ— Applying the pattern can be overkill if a state machine has only a few states and rarely changes

When to Apply

  • β†’ When you have an object that behaves differently depending on its current state, the number of states is enormous, and the state-specific code changes frequently
  • β†’ When you have a class polluted with massive conditionals that alter how the class fields behave

When to Avoid

  • ! When the object has only 2 trivial boolean states (e.g. active / inactive)