Patterns Worth Knowing
Loading
Loading
Patterns Worth Knowing
Strategy, Observer, Command, State and Template Method — the patterns about what happens, and when.
By the end of this chapter
These have nearly identical diagrams — an interface, several implementations, a context holding one — and are told apart by a single question: who decides which implementation is in use?
| Strategy | State | |
|---|---|---|
| Chosen by | The caller, usually at construction | The object itself, as events arrive |
| Changes during a lifetime | Rarely | Constantly — that is the point |
| Implementations know each other | No | Yes — each returns the next |
| Example | A pricing rule | A vending machine's mode |
The Parking Garage exercise uses Strategy for its fee policy. The Vending Machine exercise uses State for its modes. Building both is the clearest way to feel the difference.
**Problem.** An action needs to be more than a method call — it needs to be stored, queued, logged, retried or undone.
**Shape.** Wrap the action and its parameters in an object with an `execute()` method, and optionally an `undo()`. Once an action is an object it can go in a list, and a list of actions is a history.
interface Command { void execute(); void undo();} // Undo is now a stack, not a special case in every handler.final class CommandHistory { private final Deque<Command> done = new ArrayDeque<>(); void run(Command command) { command.execute(); done.push(command); } void undoLast() { if (!done.isEmpty()) done.pop().undo(); }}**Problem.** Several things must react when something happens, and the thing it happens to should not know who they are.
**Shape.** The subject holds a list of listeners and notifies them. Adding a reaction does not open the subject.
**Shape.** A base class defines the skeleton of an algorithm and leaves named steps abstract for subclasses to fill in.
It works, and it is worth recognising in code you did not write. But it is Strategy implemented with inheritance, and it inherits inheritance's problems: one algorithm shape per subclass, no runtime change, and subclasses coupled to the base class's internal call order. Composing strategies gets the same result with less coupling, and that is the default worth reaching for.
Sign in to keep a note here. It is free, and nobody else can see it.
Sign inWhat this chapter was for: