On this page
13. Command
The Command pattern is a behavioral design pattern that encapsulates a request as an object, thereby allowing parameterization of clients with different requests, queuing of requests, and logging of the requests. It also provides support for undoable operations.
Key Characteristics:
- Encapsulation of Requests: Encapsulates a request as an object, allowing for parameterization and storage.
- Decoupling: Decouples the sender of the request from the object that performs the action.
- Support for Undo/Redo: Enables undo and redo functionality by storing commands as objects.
How It Works:
- Command Interface: Defines an interface for executing commands.
- Concrete Commands: Implement the command interface and define the binding between a receiver and an action.
- Receiver: The object that performs the actual work.
- Invoker: Asks the command to execute the request.
- Client: Creates and configures commands and associates them with invokers.
Example in PHP:
// Command Interface
interface Command {
public function execute();
}
// Receiver
class Light {
public function on() {
echo "Light is ON\n";
}
public function off() {
echo "Light is OFF\n";
}
}
// Concrete Command for turning on the light
class LightOnCommand implements Command {
private $light;
public function __construct(Light $light) {
$this->light = $light;
}
public function execute() {
$this->light->on();
}
}
// Concrete Command for turning off the light
class LightOffCommand implements Command {
private $light;
public function __construct(Light $light) {
$this->light = $light;
}
public function execute() {
$this->light->off();
}
}
// Invoker
class RemoteControl {
private $command;
public function setCommand(Command $command) {
$this->command = $command;
}
public function pressButton() {
$this->command->execute();
}
}
// Client Code
$light = new Light();
$lightOn = new LightOnCommand($light);
$lightOff = new LightOffCommand($light);
$remote = new RemoteControl();
$remote->setCommand($lightOn);
$remote->pressButton(); // Output: Light is ON
$remote->setCommand($lightOff);
$remote->pressButton(); // Output: Light is OFF
Explanation:
- Command Interface: Command defines the execute() method that concrete commands must implement.
- Concrete Commands: LightOnCommand and LightOffCommand are concrete implementations of the Command interface. They bind the Light receiver to specific actions (turning on or off).
- Receiver: Light class performs the actual work of turning the light on and off.
- Invoker: RemoteControl holds a reference to a Command object and triggers its execution.
- Client Code: Configures the commands and associates them with the invoker.
Benefits:
- Decoupling: Separates the sender of a request from the object that processes the request.
- Flexibility: Allows for the creation of complex command sequences and supports undo/redo operations.
- Parameterization: Commands can be parameterized and stored for later execution.
Use Cases:
- GUI Systems: To handle user actions such as button clicks and menu selections.
- Transaction Systems: To manage undo and redo functionality.
- Queuing Operations: To queue and execute commands at a later time.
The Command pattern is useful for encapsulating requests, decoupling senders and receivers, and supporting complex command management scenarios, including undo and redo operations.