creational

State

Allow an object to alter its behavior when its internal state changes.

Some objects behave differently depending on what state they are in. An order that is draft, paid, shipped or cancelled allows different actions in each one.

Written with conditionals, every method starts by checking the state. The same checks appear again and again. Adding a state means finding and updating all of them, and missing one is easy.

State gives each state its own class. The object delegates to whichever state it is currently in, and that class knows how to behave.

What the interviewer is probing.

1. "What problem does State solve?" *Probing:* the motivation. *Stalls:* "State." *Moves up:* behaviour that changes with internal state, replacing a large conditional on a state field with one class per state.

2. "How does it differ from Strategy structurally?" *Probing:* the comparison. *Stalls:* "It does not." *Moves up:* structurally almost identical; the difference is intent — states know about each other and drive transitions, strategies do not.

3. "Where should transitions live?" *Probing:* the design question. *Stalls:* "Anywhere." *Moves up:* either in the state classes or in a central table — the table is easier to audit when the machine grows.

4. "When is an explicit state machine library better?" *Probing:* judgement. *Stalls:* "Never." *Moves up:* once there are many states and guarded transitions, where a declarative definition is far easier to reason about and test.

A vending machine — idle shows items, has-money accepts selection, dispensing delivers product.

Key Concepts

1
One interface defines the actions available, such as pay(), ship() and cancel().
pay()ship()cancel()
2
Each state implements it in its own way. PaidState.ship() works. DraftState.ship() rejects the call, because you cannot ship something unpaid.
PaidState.ship()DraftState.ship()
3
The main object holds a reference to its current state and forwards calls to it. It contains no conditionals at all.
4
Transitions happen by replacing that reference. After pay() succeeds, the object swaps its state to PaidState, and every later call automatically follows the new rules.
pay()PaidState
java
public interface OrderState {
    void next(Order order);
    void prev(Order order);
    String getStatus();
}
public class PendingState implements OrderState {
    public void next(Order o) { o.setState(new ProcessingState()); }
    public void prev(Order o) { System.out.println("Already at initial"); }
    public String getStatus() { return "PENDING"; }
}
public class Order {
    private OrderState state = new PendingState();
    public void setState(OrderState s) { this.state = s; }
    public void nextPhase() { state.next(this); }
    public String getStatus() { return state.getStatus(); }
}