@ryan.murray
The Command design pattern is a behavioral pattern that is used to encapsulate a request as an object, allowing the request to be parameterized with different arguments, queued, logged, or even undoable. In PHP, you can implement the Command pattern for undoable operations as follows:
1 2 3 4 |
interface Command { public function execute(); public function undo(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class ConcreteCommand implements Command { private $receiver; private $state; public function __construct(Receiver $receiver, $state) { $this->receiver = $receiver; $this->state = $state; } public function execute() { $this->receiver->performOperation($this->state); } public function undo() { $this->receiver->undoOperation($this->state); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Receiver { private $state; public function performOperation($state) { // Perform the operation $this->state = $state; } public function undoOperation($state) { // Undo the operation $this->state = null; } public function getState() { return $this->state; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Invoker { private $history = []; public function execute(Command $command) { $command->execute(); $this->history[] = $command; } public function undo() { $command = array_pop($this->history); if ($command) { $command->undo(); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$receiver = new Receiver(); $invoker = new Invoker(); $command1 = new ConcreteCommand($receiver, 'state1'); $command2 = new ConcreteCommand($receiver, 'state2'); $invoker->execute($command1); $invoker->execute($command2); echo $receiver->getState(); // Outputs 'state2' $invoker->undo(); echo $receiver->getState(); // Outputs 'state1' $invoker->undo(); echo $receiver->getState(); // Outputs null |
In the above example, we created a ConcreteCommand class that encapsulates an operation on a Receiver object. We also created an Invoker class that maintains a history of executed commands and can undo them. Finally, we created an instance of the Receiver and Invoker classes, and used them to execute and undo commands.
@ryan.murray
The Command design pattern is a behavioral design pattern that provides a way to encapsulate a request as an object, thereby allowing the request to be parameterized with different arguments, queued, logged, or even undone.
To implement the Command design pattern in PHP for undoable operations, you can follow these steps:
1 2 3 4 |
interface Command { public function execute(); public function undo(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class AddProductCommand implements Command { protected $product; protected $quantity; protected $cart; public function __construct(Product $product, $quantity, Cart $cart) { $this->product = $product; $this->quantity = $quantity; $this->cart = $cart; } public function execute() { $this->cart->addProduct($this->product, $this->quantity); } public function undo() { $this->cart->removeProduct($this->product); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Invoker { protected $history = []; public function execute(Command $command) { $command->execute(); $this->history[] = $command; } public function undo() { $command = array_pop($this->history); if ($command) { $command->undo(); } } } |
1 2 3 4 5 6 7 8 9 |
$product = new Product('Apple', 0.5); $cart = new Cart(); $command = new AddProductCommand($product, 2, $cart); $invoker = new Invoker(); $invoker->execute($command); // To undo the last command $invoker->undo(); |
This implementation will allow you to encapsulate different operations as Command objects and execute them using the Invoker. The Invoker will keep track of the undo history, allowing you to undo any previous command.