Behavioral Objects for States FSM

State

State is a behavioral pattern that lets an object switch its entire behavior at runtime by delegating to one of several interchangeable state objects, so from the outside it looks as though the object's class changed.

Complexity
Popularity

Problem

A traffic light controller has to behave completely differently depending on which color is lit: Red means stop and wait, Yellow means caution and get ready to switch, Green means go. Each color also has its own duration and its own idea of what the next color should be.

The natural first attempt is one `TrafficLight` class with a `color` field and an `if`/`else` chain (or a `switch`) inside `tick()` that checks the current color to decide how long to stay lit and what to switch to next. Every branch needs to know about every other color just to figure out where to go next, so adding a fifth state - a flashing amber for night mode, say - means touching the same sprawling `tick()` method again. The branches keep growing denser as more colors and edge cases pile in, and it's easy to wire a transition to the wrong color while editing a neighboring branch.

Solution

State takes each branch of that `tick()` chain and turns it into its own class - `RedState`, `YellowState`, `GreenState` - each implementing a common `TrafficLightState` interface with a `handle()` method. The original object, now called the context (`TrafficLight`), stops asking "what color am I" and instead just forwards every `tick()` call to whichever state object it currently holds.

A concrete state's `handle()` does whatever that color should do, and then transitions the context to the next state in the cycle - `RedState` hands off to `YellowState`, `YellowState` to `GreenState`, and `GreenState` back to `RedState`. The context's own code never branches on color at all; it just holds a reference to the current state and delegates, while every state-specific decision and every transition lives inside the state classes themselves.

When to Use

  • Reach for State when an object's behavior depends heavily on which of several states it's in, and that set of states keeps growing.
  • Use it when a class is dominated by conditionals that all check the same status field to decide how to act.
  • Consider it when several near-identical states share so much duplicated transition logic that a shared base state class would remove the repetition.

Real-World Examples

  • **Traffic lights** - a signal controller behaves differently in the Red, Yellow, and Green states, each dictating what the next state and timing will be.
  • **Order fulfillment workflows** - an e-commerce order moves through Pending, Processing, Shipped, Delivered, and Cancelled, each allowing a different set of actions.
  • **TCP sockets** - a connection moves through Listen, Established, and Closed, reacting differently to the same incoming packet depending on which one it's in.