命令模式也叫事务模式,饭馆例子就是最好的解释了。我们是点菜就相当于命令的下达者;服务员就相当于命令接受者;厨师相当于命令的执行者。当你需要点菜或者修改菜单的时候(或者做什么新菜)就叫服务员;服务员会告诉给厨师听(炒鱼,做虾);
优点:我们不用直接和厨师交流。我们可以下达多个命令,然后服务员可以把多个命令告诉不同的厨师处理。
定义服务员代码
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();