一、意圖
將一個請求封裝為一個對象,從而使用你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日志,以及支持可撤消的操作。
可變的方面是:何時,怎樣滿足一個請求
命令模式是對命令的封裝。命令模式把發出命令的責任和執行命令的責任分割開,委派給不同的對象。
請求的一方發出請求要求執行一個操作;接收的一方收到請求,並執行操作。命令模式允許請求的一方和接收的一方獨立開來,使得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎麼被接收,以及操作是否被執行、何時被執行,以及是怎麼被執行的。
二、命令模式結構圖
三、命令模式中主要角色
命令(Command)角色:聲明了一個給所有具體命令類的抽象接口。這是一個抽象角色。
具體命令(ConcreteCommand)角色:定義一個接受者和行為之間的弱耦合;實現Execute()方法,負責調用接收考的相應操作。Execute()方法通常叫做執行方法。
客戶(Client)角色:創建了一個具體命令(ConcreteCommand)對象並確定其接收者。
請求者(Invoker)角色:負責調用命令對象執行請求,相關的方法叫做行動方法。
接收者(Receiver)角色:負責具體實施和執行一個請求。任何一個類都可以成為接收者,實施和執行請求的方法叫做行動方法。
四、命令模式的優點
命令模式的優點:
1、命令模式把請求一個操作的對象與知道怎麼執行一個操作的對象分離開。
2、命令類與其他任何別的類一樣,可以修改和推廣。
3、可以把命令對象聚合在一起,合成為合成命令。
4、可以很容易的加入新的命令類。
命令模式的缺點:可能會導致某些系統有過多的具體命令類。
五、命令模式適用場景
1、抽象出待執行的動作以參數化對象。Command模式是回調機制的一個面向對象的替代品。
2、在不同的時刻指定、排列和執行請求。
3、支持取消操作。
4、支持修改日志。
5、用構建在原語操作上的高層操作構造一個系統。Command模式提供了對事務進行建模的方法。Command有一個公共的接口,使得你可以用同一種方式調用所有的事務。同時使用該模式也易於添加新事務以擴展系統。
六、命令模式與其它模式
合成模式(composite模式):Composite模式可被實現宏命令
原型模式(prototype模式):如果命令類帶有clone(或在之前的文章中提到的copy方法)方法,命令就可以被復制。在命令模式支持多次取消操作時可能需要用到此模式,以復制當前狀態的Command對象
七、命令模式PHP示例
<?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、Client創建一個ConcreteCommand對象並指定它的Receiver對象
2、某Invoker對象存儲該ConcreteCommand對象
3、該Invoker通過調用Command對象的execute操作來提交一個請求。若該命令是可撤消的,ConcreteCommand就在執行execute操作之前存儲當前狀態以用於取消命令。
4、ConcreteCommand對象對調用它的Receiver的一些操作以執行該請求。
九、宏命令
在這裡,我們以一個簡單的增加和粘貼功能為例,將這兩個命令組成一個宏命令。
我們可以新建復制命令和粘貼命令,然後將其添加到宏命令中去。
如下所示代碼:
<?php
/**
* 命令角色
*/
interface Command {
/**
* 執行方法
*/
public function execute();
}
/**
* 宏命令接口
*/
interface MacroCommand extends Command {
/**
* 宏命令聚集的管理方法,可以刪除一個成員命令
* @param Command $command
*/
public function remove(Command $command);
/**
* 宏命令聚集的管理方法,可以增加一個成員命令
* @param Command $command
*/
public function add(Command $command);
}
class DemoMacroCommand implements MacroCommand {
private $_commandList;
public function __construct() {
$this->_commandList = array();
}
public function remove(Command $command) {
$key = array_search($command, $this->_commandList);
if ($key === FALSE) {
return FALSE;
}
unset($this->_commandList[$key]);
return TRUE;
}
public function add(Command $command) {
return array_push($this->_commandList, $command);
}
public function execute() {
foreach ($this->_commandList as $command) {
$command->execute();
}
}
}
/**
* 具體拷貝命令角色
*/
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, ' do copy action.<br />';
}
/**
* 粘貼方法
*/
public function paste() {
echo $this->_name, ' do paste 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');
$pasteCommand = new PasteCommand($receiver);
$copyCommand = new CopyCommand($receiver);
$macroCommand = new DemoMacroCommand();
$macroCommand->add($copyCommand);
$macroCommand->add($pasteCommand);
$invoker = new Invoker($macroCommand);
$invoker->action();
$macroCommand->remove($copyCommand);
$invoker = new Invoker($macroCommand);
$invoker->action();
}
}
Client::main();
?>
以上就是使用php實現命令模式的代碼,還有一些關於命令模式的概念區分,希望對大家的學習有所幫助。