The Command Design Pattern: Turning Actions into Objects
Master the Command Pattern in Java. Learn how to encapsulate requests as objects to enable Undo/Redo, queuing, and macro commands.
Moshiour Rahman
Advertisement
The Problem: Hardcoded Buttons
Imagine you are building a Universal Remote Control. It has 4 buttons. If you code it like this:
class Remote {
private Light light;
private TV tv;
public void pressButton1() {
light.on(); // Hardcoded!
}
public void pressButton2() {
tv.volumeUp(); // Hardcoded!
}
}
This is rigid. You can’t change what Button 1 does at runtime. You can’t “record” a macro of clicks. You can’t “Undo”.
The Solution: The Command Pattern
The Command Pattern turns a request into a stand-alone object. This lets you parameterize methods with different requests, delay or queue a request’s execution, and support undoable operations.
Real-Life Analogy: Ordering at a Diner 🍔
- You (Client): Give an order (“Burger, no onions”) to…
- The Waiter (Invoker): Takes the order, writes it on a ticket (Command Object).
- The Cook (Receiver): Reads the ticket and cooks the burger.
The waiter doesn’t need to know how to cook a burger. They just hold the Command (Ticket) and pass it to the receiver.
Visualizing the Pattern

Implementation
1. The Command Interface
public interface Command {
void execute();
void undo(); // Critical for Undo features
}
2. The Receiver (The Hardware)
public class Light {
public void on() { System.out.println("Light ON"); }
public void off() { System.out.println("Light OFF"); }
}
3. Concrete Commands
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off(); // Simple undo logic
}
}
4. The Invoker (The Remote)
public class RemoteControl {
private Command slot;
public void setCommand(Command command) {
this.slot = command;
}
public void pressButton() {
slot.execute();
}
public void pressUndo() {
slot.undo();
}
}
Usage
RemoteControl remote = new RemoteControl();
Light livingRoomLight = new Light();
// Create the 'ticket'
Command lightOn = new LightOnCommand(livingRoomLight);
// Load the remote
remote.setCommand(lightOn);
// Press button
remote.pressButton(); // Output: Light ON
// Oops, didn't mean to
remote.pressUndo(); // Output: Light OFF
In The Wild (Real World Examples)
1. java.lang.Runnable
One of the interface definitions of Command is simply void execute(). Does that look familiar? Runnable is effectively a Command interface. Thread pools execute Runnables.
2. GUI Actions (Swing Action / JavaFX)
Text Editors use Command pattern heavily for Check/Undo operations on Ctrl+Z.
Cheat Sheet
| Feature | Details |
|---|---|
| Category | Behavioral |
| Problem Solved | Need for Undo/Redo, Job Queues, Macros |
| Key implementation | execute() method in an interface |
| Pros | Decoupling (Invoker doesn’t know Receiver), Undo/Redo support |
| Cons | Lots of tiny classes for every single action |
Tips to Remember 🧠
- “The Ticket”: Think of the diner order ticket. It’s an object representing an action.
- “Undo”: If you need Undo/Redo, you almost certainly need Command. You typically keep a
Stack<Command>history.
Advertisement
Moshiour Rahman
Software Architect & AI Engineer
Enterprise software architect with deep expertise in financial systems, distributed architecture, and AI-powered applications. Building large-scale systems at Fortune 500 companies. Specializing in LLM orchestration, multi-agent systems, and cloud-native solutions. I share battle-tested patterns from real enterprise projects.
Related Articles
The Visitor Design Pattern: Add Operations Without Modifying Classes
Master the Visitor Pattern in Java. Learn how to add new operations to object structures using double dispatch.
JavaThe Observer Design Pattern: Don't Call Us, We'll Call You
Master the Observer Pattern in Java. Learn how to implement event-driven architectures and decouple data sources from listeners.
JavaThe Mediator Design Pattern: Centralize Complex Communications
Master the Mediator Pattern in Java. Learn how to reduce coupling by having objects communicate through a mediator instead of directly.
Comments
Comments are powered by GitHub Discussions.
Configure Giscus at giscus.app to enable comments.