设计模式 --命令模式

命令模式也叫事务模式,饭馆例子就是最好的解释了。我们是点菜就相当于命令的下达者;服务员就相当于命令接受者;厨师相当于命令的执行者。当你需要点菜或者修改菜单的时候(或者做什么新菜)就叫服务员;服务员会告诉给厨师听(炒鱼,做虾);

优点:我们不用直接和厨师交流。我们可以下达多个命令,然后服务员可以把多个命令告诉不同的厨师处理。

定义服务员代码

class Invoker{
   //存命令的变量
   public command;
   
   //初始化命令
   public function __construct($command){
   $this->command = $command
  }

  //传达命令
  public function exec(){
  $this->command->execute();
}

}

定义命令的抽象类;这个作用是为了定义真正的执行者是谁。

abstract class Command {
  //命令的执行者 厨师
  protected $receiver;

  //构造厨师实例化
  public function __construct(Receiver $receiver){
  $this->receiver = $receiver;
}

  //服务员把命令告诉厨师
  abstract function execute();
}

//炒鱼类
class ConcreteACommand extends Command{
  //炒鱼了喂
  public function execute(){
   $this->receiver->action();
}
}

//炒虾类
class ConcreteBCommand extends Command{
  public function execute(){
   $this->receiver->action();
}
}

厨师类

class Receiver{

//厨师的名称
 public $name;

 function __construct($name){
 $this->name = $name;
 }

 //该厨师的方法 (会做哪种菜)
 public function action(){
  echo $this->name."我在做某菜";
}
}

测试

//先有厨师 (不然谁做饭?开啥店)
$receiverA = new Receiver("李厨师");

//我来吃饭下单 让厨师给我做条鱼吃吃
$command = new ConcreteACommand($receiverA)
//当然也可以做虾等等。。。。


//服务员 把 我的下单告诉厨师
$invoker = new Invoker($command);
$invoker->exec(); //告诉厨师就好,厨师怎么做出来是厨师的事

以上就是基本的命令模式了,但是还可以多命令多厨师(大饭堂不止一个厨师;一个餐单吧?)

<?php

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;
    }
}

// 准备执行者
$receiverA = new Receiver('A');
$receiverB = new Receiver('B');
$receiverC = new Receiver('C');

// 准备命令
$commandOne = new ConcreteCommand($receiverA, 'A');
$commandTwo = new ConcreteCommand($receiverA, 'B');
$commandThree = new ConcreteCommand($receiverA, 'C');

// 请求者
$invoker = new Invoker();
$invoker->setCommand($commandOne);
$invoker->setCommand($commandTwo);
$invoker->setCommand($commandThree);
$invoker->exec();
$invoker->undo();

// 新加一个单独的执行者,只执行一个命令
$invokerA = new Invoker();
$invokerA->setCommand($commandOne);
$invokerA->exec();

// 命令A已经执行了,再次执行全部的命令执行者,A命令的state判断无法生效
$invoker->exec();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值