Middle+
Do you use the Command pattern in your work?
sobes.tech AI
Answer from AI
Yes, I use the Command pattern in my work.
The Command pattern encapsulates a request as an object, allowing parameterization of clients with different requests, queuing or logging requests, and supporting undo operations.
I apply it when:
- It is necessary to parameterize objects with an action.
- Operations need to be queued, scheduled, or logged.
- An undo or redo mechanism is required.
- Low-level operations should be adapted for high-level components.
Examples of usage:
- Graphical user interface systems where commands correspond to user actions (e.g., "Insert", "Copy").
- Transaction management systems.
- Distributed systems and message queues.
- Macro or script implementations.
Structurally, the pattern includes:
Command: an interface or abstract class declaring the method for executing an operation.ConcreteCommand: a specific implementation ofCommand, linking the receiver with an action. Contains a reference toReceiver.Client: creates aConcreteCommandobject and sets the receiver.Invoker: calls the command execution. It holds aCommandobject.Receiver: the object that performs the actual action.
Example: A simple implementation of a command to toggle a light.
// Command interface
interface Command {
void execute();
void undo(); // For undo support
}
// Receiver
class Light {
private boolean isOn = false;
public void turnOn() {
isOn = true;
System.out.println("Light is ON");
}
public void turnOff() {
isOn = false;
System.out.println("Light is OFF");
}
}
// Concrete command to turn on the light
class TurnOnLightCommand implements Command {
private Light light;
public TurnOnLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
@Override
public void undo() {
light.turnOff(); // Undo turn on
}
}
// Concrete command to turn off the light
class TurnOffLightCommand implements Command {
private Light light;
public TurnOffLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
@Override
public void undo() {
light.turnOn(); // Undo turn off
}
}
// Invoker
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
public void pressUndoButton() {
command.undo(); // Undo
}
}
// Client
public class Client {
public static void main(String[] args) {
Light livingRoomLight = new Light(); // Receiver
Command turnOn = new TurnOnLightCommand(livingRoomLight); // Concrete command
Command turnOff = new TurnOffLightCommand(livingRoomLight);
RemoteControl remote = new RemoteControl(); // Invoker
remote.setCommand(turnOn);
remote.pressButton(); // Light is ON
remote.pressUndoButton(); // Light is OFF
remote.setCommand(turnOff);
remote.pressButton(); // Light is OFF
remote.pressUndoButton(); // Light is ON
}
}
Comparison table with other patterns:
| Pattern | Main purpose | Difference from Command |
|---|---|---|
| Strategy | Defines a family of algorithms and encapsulates each one. | Encapsulates an entire algorithm (what to do), whereas Command is a specific action (how to do). |
| Observer | Defines a one-to-many dependency between objects. | Relates to notifications about state changes, not request execution. |
| Memento | Saves and restores an object's state without breaking encapsulation. | Used for saving state, not for encapsulating actions. |