Java Command Pattern
In this page:
What is the Command Pattern?
The Command pattern encapsulates a request as a standalone object, typically with a single execute method, turning an action into something that can be stored, passed around, and invoked without the caller needing to know its details.
Example: What is the Command Pattern?
public class Main {
interface Command { void execute(); }
public static void main(String[] args) {
Command turnOn = () -> System.out.println("Light turned on"); // a request as a standalone object
turnOn.execute();
}
}
Login to try C/C++/Java/PHP code in the editor
Encapsulating a Request
A command decouples the object that invokes an action (the invoker) from the object that actually performs it (the receiver), since the invoker only ever calls execute on whatever command it's been given.
Example: Encapsulating a Request
public class Main {
static class Light { void on() { System.out.println("Light on"); } }
interface Command { void execute(); }
static class LightOnCommand implements Command {
Light light;
LightOnCommand(Light light) { this.light = light; }
public void execute() { light.on(); } // invoker only calls execute
}
public static void main(String[] args) {
Command cmd = new LightOnCommand(new Light());
cmd.execute();
}
}
Login to try C/C++/Java/PHP code in the editor
Undo and Redo
Adding an undo method alongside execute lets each command know how to reverse its own effect, and storing executed commands in a stack provides a natural way to implement multi-level undo and redo.
Example: Undo and Redo
import java.util.*;
public class Main {
interface Command { void execute(); void undo(); }
public static void main(String[] args) {
StringBuilder text = new StringBuilder();
Deque<Command> history = new ArrayDeque<>();
Command append = new Command() {
public void execute() { text.append("Hi"); }
public void undo() { text.setLength(text.length() - 2); }
};
append.execute();
history.push(append);
history.pop().undo(); // reverses its own effect
System.out.println("'" + text + "'");
}
}
Login to try C/C++/Java/PHP code in the editor
Command Queues
Because a command is just an object, multiple commands can be collected into a queue or list and processed later, in order, enabling features like task scheduling, batching, or logging of requests before they run.
Example: Command Queues
import java.util.*;
public class Main {
interface Command { void execute(); }
public static void main(String[] args) {
Queue<Command> queue = new LinkedList<>();
queue.add(() -> System.out.println("Task 1"));
queue.add(() -> System.out.println("Task 2")); // collected, processed later in order
while (!queue.isEmpty()) queue.poll().execute();
}
}
Login to try C/C++/Java/PHP code in the editor
Command vs Direct Method Calls
A direct method call tightly couples the caller to a specific class and method, while wrapping the same action in a Command object decouples them, letting the invoker work with any command without knowing what it actually does.
Example: Command vs Direct Method Calls
public class Main {
static class Light { void on() { System.out.println("Light on"); } }
interface Command { void execute(); }
public static void main(String[] args) {
Light light = new Light();
light.on(); // tightly coupled direct call
Command cmd = light::on; // decoupled -- invoker doesn't know it's a Light
cmd.execute();
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first:
- Java Design Patterns Introduction
- Java Singleton Pattern
- Java Factory Pattern
- Java Observer Pattern
- Java Builder Pattern
- Java MVC Architecture
- Java Adapter Pattern
- Java Decorator Pattern
- Java Strategy Pattern
- Java Command Pattern
- Java Facade Pattern
- Java Proxy Pattern
- Java Template Method Pattern
- Java Repository Pattern