0%
- 概念
- 将一个请求封装(命令的封装)为一个对象,从而使用你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
- 命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分隔开,委派给不同的对象。
- 请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
- 角色
- 命令(command)角色:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色。
- 具体命令(ConcreteCommand)角色:定义一个接收者和行为之间的弱耦合;实现Execute()方法,负责调用接收到的相应操作。Execute()方法通常叫做执行方法。
- 客户(client)角色:创建了一个具体命令(ConcreteCommand)对象并确定其接收者。
- 请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
- 接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
- 优点和缺点
- 优点:
- 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分离开。
- 命令类与其他任何别的类一样,可以修改和推广。
- 可以把命令对象聚合在一起,合成为合成命令。
- 可以很容易的加入新的命令类。
- 缺点:
- 应用场景
- 抽象出待执行的动作以参数化对象。Command模式是回调机制的一个面向对象的替代品。
- 在不同的时刻指定、排列和执行请求。
- 支持取消操作
- 支持修改日志
- 用构建在原语操作上的高层操作构建一个系统。Command模式提供了对事务进行建模的方法。Command有一个公共的接口,使得你可以用同一种方式调用所有的事务。同时使用该模式也易于添加新事务以扩展系统。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
| <?php
interface Command { public function execute(); }
interface MacroCommand extends Command { public function remove(Command $command);
public function add(Command $command); }
class CopyCommand implements Command { private $receiver; public function __construct(Receiver $receiver) { $this->receiver = $receiver; }
public function execute() { $this->receiver->copy(); } }
class PasteCommand implements Command { private $receiver; public function __construct(Receiver $receiver) { $this->receiver = $receiver; }
public function execute() { $this->receiver->paste(); } }
class Receiver { private $name; public function __construct($name) { $this->name = $name; }
public function copy() { echo $this->name . '执行copy命令'; }
public function paste() { echo $this->name . '执行paste命令'; } }
class Invoker { private $command; public function __construct(Command $command) { $this->command = $command; }
public function action() { $this->command->execute(); } }
class TestMacroCommand implements MacroCommand { private $commands;
public function __construct() { $this->commands = []; } public function remove(Command $command) { $index = array_search($command, $this->commands); if ($index === false) { return false; } else { unset($this->commands[$index]); return true; } }
public function add(Command $command) { return array_push($this->commands, $command); }
public function execute() { if (!is_array($this->commands)) { return false; } else { foreach ($this->commands as $command) { $command->execute(); } }
return true; } }
$receiver = new Receiver('gd'); $copy_command = new CopyCommand($receiver); $paste_command = new PasteCommand($receiver);
$macro_command = new TestMacroCommand(); $macro_command->add($copy_command); $macro_command->add($paste_command);
$invoker = new Invoker($macro_command); $invoker->action();
|