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();