Command Design Pattern in PHP

1. Definition

The Command design pattern is a behavioral design pattern that turns a request into a stand-alone object containing information about the request. This decoupling allows the sender and receiver to be developed independently.

2. Problem Statement

Imagine you have a GUI application with lots of buttons. If each button is hardcoded to perform a specific action, adding or changing buttons will become complicated. Also, if you want to support undo, redo, or logging operations, the code will become even messier.

3. Solution

The Command pattern suggests that GUI objects (like buttons) shouldn't send a request directly. Instead, the object should delegate this call to a separate command object. The command object has a single action method that triggers the request's desired action.

4. Real-World Use Cases

1. GUI buttons and menu items in an application.

2. Implementing multi-level undo/redo functionality in software.

3. Operations queue: A sequence of commands can be assembled and executed as a batch.

5. Implementation Steps

1. Define a command interface with an execute method.

2. Implement one or more concrete classes for the command interface, each representing a specific operation.

3. Create invoker classes that use command objects.

4. The client or a factory can then create command objects and set them on the invoker.

6. Implementation in PHP

<?php
// Command Interface
interface Command {
    public function execute(): void;
}
// Concrete Command
class LightOnCommand implements Command {
    private $light;
    public function __construct($light) {
        $this->light = $light;
    }
    public function execute(): void {
        $this->light->turnOn();
    }
}
// Receiver
class Light {
    public function turnOn(): void {
        echo "Light is ON\n";
    }
}
// Invoker
class RemoteControl {
    private $command;
    public function setCommand(Command $cmd) {
        $this->command = $cmd;
    }
    public function pressButton() {
        $this->command->execute();
    }
}
// Client Code
$light = new Light();
$lightOn = new LightOnCommand($light);
$remote = new RemoteControl();
$remote->setCommand($lightOn);
$remote->pressButton();
?>

Output:

Light is ON

Explanation:

1. Command: This is an interface for executing operations.

2. LightOnCommand: A concrete command that encapsulates the request to the Light receiver.

3. Light: The receiver class. It performs the actual operations.

4. RemoteControl: This is the invoker. It asks the command to carry out the request.

The Client (in this case, a simple test) creates command objects sets them up with its corresponding receivers, and then associates the command with an invoker (RemoteControl).

7. When to use?

Use the Command pattern when:

1. You want to decouple classes that invoke operations from classes that perform operations.

2. You need to parameterize objects with operations.

3. You need to queue operations, schedule them, or execute them remotely.

4. You want to support undoable operations.


Comments