Design Patterns

State & Execution Patterns

Command, Template Method, and State — behavioral patterns for encapsulating actions, standardizing workflows, and managing state transitions.

Suggest an edit

State & Execution Patterns

While some behavioral patterns focus on routing messages (like Observer), others focus on how an action is encapsulated, scheduled, or executed over time.

💡 The core idea. You can turn an action or a state into a standalone object. This lets you pass actions around as variables, queue them, undo them, or allow an object to completely change its behavior as its internal state changes.

You'll be able to:

  • Encapsulate a request as an object to support queues and undo operations (Command).
  • Define the skeleton of an algorithm while letting subclasses fill in the steps (Template Method).
  • Allow an object to alter its behavior when its internal state changes (State).

📘 How to read the Intuition boxes. As you read, look for the Mechanism and Concrete bite under each code block. They map the code you just saw to the mental model you need to build.

  1. Command Pattern
  2. Template Method Pattern
  3. State Pattern

1. Command Pattern

The Command Pattern encapsulates a request as an object. This lets you parameterize methods with different requests, delay or queue a request's execution, and support undoable operations.

Instead of a UI button directly calling light.turnOn(), the button calls execute() on a Command object that it holds.

Output:

Light is ON
Light is OFF
-- Undoing --
Light is ON
Light is OFF

Analysis. The RemoteControl is completely decoupled from the Light. Because the action is encapsulated in a Command object, the remote can store a history of executed commands and support undo() by popping the stack.

Intuition.

  • Mechanism. Wrap a request inside an object that has an execute() method. Pass this object to the invoker.
  • Concrete bite. Ordering food at a restaurant. You tell the waiter what you want (the Command). The waiter writes it on a ticket and puts it on the kitchen queue. The chef (the Receiver) eventually cooks it.

💡 Earned rule. Use Command when you need to queue operations, schedule their execution, or support undo/redo. The cost is a slew of small classes for every possible action.

2. Template Method Pattern

The Template Method Pattern defines the skeleton of an algorithm in a superclass, but lets subclasses override specific steps of the algorithm without changing its overall structure.

Output:

Making tea:
Boiling water
Steeping the tea
Pouring into cup
Adding lemon
 
Making coffee:
Boiling water
Dripping coffee through filter
Pouring into cup
Adding sugar and milk

Analysis. The makeBeverage() method defines the unchangeable workflow. TeaMaker and CoffeeMaker only provide the implementation for the varying steps (brew() and addCondiments()). This prevents code duplication for the shared steps (boilWater() and pourInCup()).

Intuition.

  • Mechanism. Create an abstract base class with a final "template method" that calls abstract placeholder methods. Subclasses implement the placeholders.
  • Concrete bite. Building a mass-production house. The architect defines the exact sequence (foundation, walls, roof), but the buyer can choose what goes inside the walls (brick vs. siding).

💡 Earned rule. Use Template Method when multiple classes share the exact same algorithm structure but differ in specific steps. The cost is rigid reliance on inheritance.

3. State Pattern

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

Instead of a giant if (state == PLAYING) ... else if (state == PAUSED) block inside a media player, you represent each state as an object, and the player delegates actions to its current state object.

Output:

Insert a coin first.
Coin accepted. You can now dispense.
Coin already inserted.
Item dispensed.

Analysis. The VendingMachine delegates insertCoin() and dispenseItem() to currentState. By swapping the currentState variable from IdleState to HasCoinState, the machine completely changes how it responds to the exact same method calls.

Intuition.

  • Mechanism. Represent states as classes. The context delegates execution to its current state object. The state objects can trigger transitions by passing a new state to the context.
  • Concrete bite. Your smartphone's power button. If the phone is locked, it wakes the screen. If the phone is unlocked, it locks it. The button does the same thing, but the phone's internal state dictates the result.

💡 Earned rule. Use the State pattern when an object behaves wildly differently depending on its current state, and you have massive conditional blocks managing these transitions. The cost is that state transition logic can become scattered across multiple state classes.

Summary

Pattern Purpose
Command Encapsulates a request as an object, allowing for queues, logging, and undo operations.
Template Method Defines an algorithm's skeleton in a base class, letting subclasses override specific steps.
State Lets an object alter its behavior when its internal state changes by delegating to a state object.

🚨 Gotcha Checklist

Symptom Likely cause Fix
The history stack in your Command pattern is consuming too much RAM. Heavy Commands. Your command objects are storing large amounts of state (like an entire file backup) for undo. Store only the delta (what changed) or use the Memento pattern to serialize state compactly.
You want to use Template Method, but Java doesn't support multiple inheritance, so you can't inherit the template. Inheritance restriction. Template Method relies heavily on inheritance. Switch to the Strategy pattern, which uses composition instead.

✅ Check yourself

How does the State pattern differ from Strategy? Structurally, they look identical.

They are structurally identical (Context -> Interface -> Concrete Implementations), but differ in intent. In Strategy, the client injects the strategy, and the strategies don't know about each other. In State, the state objects typically hold a reference to the context and trigger transitions to other states themselves.

📚 Sources

  • Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.

🧪 Predict, then check. In the Template Method pattern, can a subclass override the main template method?

If written correctly, no. In Java, the template method should be marked final so subclasses cannot break the sequence of the algorithm. They can only override the protected abstract steps.

Your Turn

Think of an algorithm in your codebase that involves fetching data, transforming it, and saving it. Create an abstract DataPipeline class with a final void execute() method that dictates this flow. Subclass it into XmlToDatabasePipeline and JsonToFilePipeline.

Mark as read