← Back to Home

State Pattern

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

What is it?

The State pattern encapsulates state-specific behavior and transitions, making objects behave differently depending on their current state.

Example

Current Light: 🔴 Red
interface TrafficLightState {
  next(context: TrafficLightContext): void;
  getColor(): string;
}

class TrafficLightContext {
  private state: TrafficLightState;

  constructor(initialState: TrafficLightState) {
    this.state = initialState;
  }

  setState(state: TrafficLightState) {
    this.state = state;
  }

  next() {
    this.state.next(this);
  }

  getColor(): string {
    return this.state.getColor();
  }
}

class RedLight implements TrafficLightState {
  next(context: TrafficLightContext): void {
    context.setState(new GreenLight());
  }

  getColor(): string {
    return '🔴 Red';
  }
}

class GreenLight implements TrafficLightState {
  next(context: TrafficLightContext): void {
    context.setState(new YellowLight());
  }

  getColor(): string {
    return '🟢 Green';
  }
}

class YellowLight implements TrafficLightState {
  next(context: TrafficLightContext): void {
    context.setState(new RedLight());
  }

  getColor(): string {
    return '🟡 Yellow';
  }
}

// Usage
const context = new TrafficLightContext(new RedLight());
console.log(context.getColor()); // 🔴 Red
context.next();
console.log(context.getColor()); // 🟢 Green
context.next();
console.log(context.getColor()); // 🟡 Yellow

Common Uses

  • UIs with multiple modes (e.g. loading, success, error)
  • Workflow engines or step-based logic
  • State-driven game logic

When to Use

  • An object must change behavior depending on state
  • State-specific logic would be too messy in one class

Caution

  • Too many states can introduce class explosion
  • Be cautious of redundant logic spread across states