将一个请求封装为一个对象,从而使用你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。
请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
例如:
<?php
/**
* 命令角色
*/
interface Command {
/**
* 执行方法
*/
public function execute();
}
/**
* 具体命令角色
*/
class ConcreteCommand implements Command {
private $_receiver;
public function __construct(Receiver $receiver) {
$this->_receiver = $receiver;
}
/**
* 执行方法
*/
public function execute() {
$this->_receiver->action();
}
}
/**
* 接收者角色
*/
class Receiver {
/* 接收者名称 */
private $_name;
public function __construct($name) {
$this->_name = $name;
}
/**
* 行动方法
*/
public function action() {
echo $this->_name, ' do action.<br />';
}
}
/**
* 请求者角色
*/
class Invoker {
private $_command;
public function __construct(Command $command) {
$this->_command = $command;
}
public function action() {
$this->_command->execute();
}
}
/**
* 客户端
*/
class Client {
/**
* Main program.
*/
public static function main() {
$receiver = new Receiver('phpppan');
$command = new ConcreteCommand($receiver);
$invoker = new Invoker($command);
$invoker->action();
}
}
Client::main();
?>
【命令模式的优点】
命令模式的优点:
1、命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分离开。
2、命令类与其他任何别的类一样,可以修改和推广。
3、可以把命令对象聚合在一起,合成为合成命令。
4、可以很容易的加入新的命令类。
命令模式的缺点:可能会导致某些系统有过多的具体命令类。
【命令模式适用场景】
1、抽象出待执行的动作以参数化对象。Command模式是回调机制的一个面向对象的替代品。
2、在不同的时刻指定、排列和执行请求。
3、支持取消操作。
4、支持修改日志。
5、用构建在原语操作上的高层操作构造一个系统。Command模式提供了对事务进行建模的方法。Command有一个公共的接口,使得你可以用同一种方式调用所有的事务。同时使用该模式也易于添加新事务以扩展系统。
【命令模式协作】
1、Client创建一个ConcreteCommand对象并指定它的Receiver对象
2、某Invoker对象存储该ConcreteCommand对象
3、该Invoker通过调用Command对象的execute操作来提交一个请求。若该命令是可撤消的,ConcreteCommand就在执行execute操作之前存储当前状态以用于取消命令。
4、ConcreteCommand对象对调用它的Receiver的一些操作以执行该请求