design patterns · high

State Pattern

State is a behavioral GoF pattern that lets an object change its behavior when its internal state changes, so it appears to change class. Each state becomes a class implementing a common State interface; the Context (e.g. Doc) holds a pointer to the current state and delegates operations to it (publish() calls state_->publish(*this)). Each concrete state implements the operation and performs the transition by calling context.setState(next) — Draft→Moderation→Published — so transition logic is distributed into the states, each knowing only its valid next states. This eliminates the repeated if/else-on-state switch in every method and is Open/Closed (adding a state is adding a class). Costs: more classes and a heap allocation per transition unless stateless states are cached/shared (flyweight). It is structurally identical to Strategy but differs in intent — Strategy is selected by the client and stays fixed for the task, while State swaps itself at runtime as the workflow advances. Compared to a std::variant state machine, State is the open, polymorphic (vtable, heap) form for extensible state sets, whereas variant suits a closed set with value semantics and visit-based exhaustiveness.

🔑 Key line

State (behavioral): make each state a class implementing a shared interface; the Context delegates the operation to its current state, and each state performs its behavior and transitions via setState(next) — removing if/else-on-state sprawl and making states Open/Closed. Same structure as Strategy but Strategy is client-picked/fixed while State self-transitions at runtime; vs std::variant (closed set, value semantics) State is the open/polymorphic form.

The code

// State — let an object change behavior when its internal state changes.
// Each state is a CLASS; the context delegates to the current one.
class Doc;
struct State {
virtual void publish(Doc&) = 0; // same action, state-specific
virtual ~State() = default;
};
class Doc {
std::unique_ptr<State> state_;
public:
Doc();
void setState(std::unique_ptr<State> s) {
state_ = std::move(s);
}
void publish() {
state_->publish(*this);
} // delegate
};
struct Draft : State {
void publish(Doc& d) override;
}; // -> Moderation
struct Moderation : State {
void publish(Doc& d) override;
}; // -> Published
struct Published : State {
void publish(Doc& d) override { /* no-op */ }
};
void Draft::publish(Doc& d) {
d.setState(std::make_unique<Moderation>());
}
void Moderation::publish(Doc& d) {
d.setState(std::make_unique<Published>());
}

What this lesson walks through

  1. 01Intent — behavior driven by state, no giant switch
  2. 02Structure — Context delegates to a State object
  3. 03Each state owns its own transitions
  4. 04Gotcha — State vs Strategy

The State pattern lets an object change its behavior when its internal state changes — it appears to change class. Instead of a sprawling switch(state) in every method, each state is its own object that knows how to behave.

See it animated — step by step, at your own pace

Unlock the full interactive walkthrough of State Pattern and 100+ animated C++ interview lessons.

← Previous
GoF Command — Requests as Objects: Undo, Redo, Macro, Queue
Next →
Template Method Pattern