php 设计模式之 命令模式



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

php 设计模式之 命令模式

上一篇:kubernetes容器编排YAML详解


下一篇:IDEA使用maven创建web工程并完善的过程