Middle
Why is the Command pattern used?
sobes.tech AI
Answer from AI
The Command pattern is used to encapsulate a request as an object, allowing:
- Parameterization of clients with different requests: A command is an object that can be stored, passed to methods, or used in collections. This enables the creation of universal classes that work with any commands without knowing their implementation details.
- Queuing requests: Commands can be placed in a queue for later execution or in a specific order. Suitable for implementing deferred operations, task schedulers, or logging systems.
- Support for undo operations: A command can contain methods for executing and undoing an action. This is used in text editors (undo/redo), games, and other applications with an action history.
- Logging changes: After executing a command, it can be recorded in a log. This is useful for restoring system state after a crash or for auditing.
- Creating transactions: A group of commands can be combined into a single transaction, which either executes entirely or is fully rolled back in case of an error.
Structurally, the pattern includes the following components:
- Command: An interface with a method for executing the operation (e.g.,
execute()). - ConcreteCommand: An implementation of the
Commandinterface that links the receiver with a specific action. It contains a reference to theReceiver. - Invoker: The class that calls the command for execution. It does not know the details of the command or its receiver.
- Receiver: The class that performs the actual action related to the command. It implements the business logic.
// Command interface
interface Command {
void execute();
// void undo(); // Optional for undo support
}
// Concrete command
class ConcreteCommand implements Command {
private final Receiver receiver;
private final String action; // Example parameter for the receiver
public ConcreteCommand(Receiver receiver, String action) {
this.receiver = receiver;
this.action = action;
}
@Override
public void execute() {
receiver.performAction(action); // Perform action via receiver
}
}
// Receiver
class Receiver {
public void performAction(String action) {
System.out.println("Performing action: " + action);
}
}
// Invoker
class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
if (command != null) {
command.execute(); // Execute the command
}
}
}
// Usage example
public class CommandPatternDemo {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver, "save file");
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.pressButton(); // Will call receiver.performAction("save file")
}
}