引自原书:
1.较容易地设计一个命令队列
2.在需要的情况下,可以容易地将命令记入日志
3.允许接收请求的一方决定是否要否决请求
4.可以容易地实现对请求的撤销和重做
5.由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易
6.命令模式把请求一个操作对象与知道怎么执行一个操作对象分割开【DP】
敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能时,把原来的代买重构为命令模式才有意义。【R2P】
//抽象命令
abstract class Command {
protected $receiver;
function __construct(Barbecuer $receiver) {
$this->receiver = $receiver;
}
//执行命令
abstract public function excuteCommand();
}
//具体命令类
//烤羊肉串命令
class BakeMuttonCommand extends Command {
function __construct(Barbecuer $receiver) {
parent::__construct($receiver);
}
public function excuteCommand() {
$this->receiver->bakeMutton();
}
}
//烤鸡翅命令
class BakeChickenWingCommand extends Command {
function __construct(Barbecuer $receiver) {
parent::__construct($receiver);
}
public function excuteCommand() {
$this->receiver->bakeChickenWing();
}
}
//烤肉串者
class Barbecuer {
//烤羊肉
public function bakeMutton() {
echo '烤羊肉串!<br/>';
}
//烤鸡翅
public function bakeChickenWing() {
echo '烤鸡翅!<br/>';
}
}
//服务员
class Waiter {
private $orders;
//设置订单
public function setOrder(Command $command) {
if($command instanceof BakeChickenWingCommand) {
echo '服务员:鸡翅没了,请点别的烧烤。<br/>';
} else if($command instanceof BakeMuttonCommand) {
$this->orders[] = $command;
echo '增加订单:烤羊肉 时间:'.date('Y-m-d H:i:s').'<br/>';
}
}
//取消订单
public function cancelOrder(Command $command) {
unset($this->orders[array_search($command, $this->orders)]);
}
//通知全部执行
public function notify() {
foreach($this->orders as $cmd) {
$cmd->excuteCommand();
}
}
}
//开店前的准备
$boy = new Barbecuer();
$bakeMuttonCommand1 = new BakeMuttonCommand($boy);
$bakeMuttonCommand2 = new BakeMuttonCommand($boy);
$bakeChickenWingCommand1 = new BakeChickenWingCommand($boy);
$girl = new Waiter();
//开门营业 顾客点菜
$girl->setOrder($bakeMuttonCommand1);
$girl->setOrder($bakeMuttonCommand2);
$girl->setOrder($bakeChickenWingCommand1);
//点菜完毕,通知厨房
$girl->Notify();
//Command类,用来声明执行操作的接口
abstract class Command {
protected $receiver;
function __construct(Receiver $receiver) {
$this->receiver = $receiver;
}
abstract public function execute();
}
class ConcreteCommand extends Command {
function __construct(Receiver $receiver) {
parent::__construct($receiver);
}
public function execute() {
$this->receiver->action();
}
}
//Invoker类,要求该命令执行这个请求。
class Invoker {
private $command;
public function setCommand(Command $command) {
$this->command = $command;
}
public function executeCommand() {
$this->command->execute();
}
}
//Receiver类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接收者
class Receiver {
public function action() {
echo '执行请求!<br/>';
}
}
$r = new Receiver();
$c = new ConcreteCommand($r);
$i = new Invoker();
$i->setCommand($c);
$i->executeCommand();