php 設計模式之 命令模式
阿新 • • 發佈:2020-12-29
1. 命令模式
命令模式,也稱為動作或者事務模式
如用餐廳舉列,選單是這個實際的命令,服務員是這個命令的傳送者,而廚師是這個命令的接收者。
那麼,這個模式解決了什麼呢?當你要修改選單的時候,只需要和服務員說就好了,她會轉達給廚師,也就是說,我們實現了顧客和廚師的解耦。也就是 呼叫者與實現者的解耦。
但是命令模式能夠做到的是 讓一個命令接收者實現多個命令(服務員下單、拿酒水、上菜),或者 把一條命令轉達給多個實現者(熱菜廚師、冷盤廚師、主食師傅)。
2. 實列
class Invoker { // 命令傳送者(服務員) private $command = []; public function setCommand(Command $command) { $this->command[] = $command; } public function exec() { // 建立 if(count($this->command) > 0){ foreach ($this->command as $command) { $command->execute(); } } } public function undo() { // 撤銷 if(count($this->command) > 0){ foreach ($this->command as $command) { $command->undo(); } } } } abstract class Command { // 執行命令內容(選單) protected $receiver; protected $state; protected $name; public function __construct(Receiver $receiver, $name) { $this->receiver = $receiver; $this->name = $name; } abstract public function execute(); } class ConcreteCommand extends Command { // 具體命令內容 public function execute() { // 具體建立方法 if (!$this->state || $this->state == 2) { $this->receiver->action(); $this->state = 1; } else { echo $this->name . '命令正在執行,無法再次執行了!', PHP_EOL; } } public function undo() { // 具體取消方法 if ($this->state == 1) { $this->receiver->undo(); $this->state = 2; } else { echo $this->name . '命令未執行,無法撤銷了!', PHP_EOL; } } } class Receiver { // 命令接收者(廚師) public $name; public function __construct($name) { $this->name = $name; } public function action() { echo $this->name . '命令執行了', PHP_EOL; } public function undo() { echo $this->name . '命令撤銷了', PHP_EOL; } } // 命令傳送者(服務員) $invoker = new Invoker(); // 命令接收者(廚師) $receiverA = new Receiver('A'); // 具體執行的命令內容(選單) $commandOne = new ConcreteCommand($receiverA, 'A'); // 執行命令 $invoker->setCommand($commandOne); $invoker->exec(); $invoker->undo(); // 新加一個單獨的執行者,只執行一個命令 $invokerA = new Invoker(); $invokerA->setCommand($commandOne); $invokerA->exec(); // 命令A已經執行了,再次執行全部的命令執行者,A命令的state判斷無法生效 $invoker->exec();