大话设计模式-命令模式

引自原书:

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


大话设计模式-命令模式_第1张图片


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


你可能感兴趣的:(大话设计模式-命令模式)