學(xué)習(xí)php設(shè)計模式 php實現(xiàn)命令模式(command)
一、意圖
將一個請求封裝為一個對象,從而使用你可用不同的請求對客戶進行參數(shù)化;對請求排隊或記錄請求日志,以及支持可撤消的操作。
可變的方面是:何時,怎樣滿足一個請求
命令模式是對命令的封裝。命令模式把發(fā)出命令的責(zé)任和執(zhí)行命令的責(zé)任分割開,委派給不同的對象。
請求的一方發(fā)出請求要求執(zhí)行一個操作;接收的一方收到請求,并執(zhí)行操作。命令模式允許請求的一方和接收的一方獨立開來,使得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎么被接收,以及操作是否被執(zhí)行、何時被執(zhí)行,以及是怎么被執(zhí)行的。
二、命令模式結(jié)構(gòu)圖
三、命令模式中主要角色
命令(Command)角色:聲明了一個給所有具體命令類的抽象接口。這是一個抽象角色。
具體命令(ConcreteCommand)角色:定義一個接受者和行為之間的弱耦合;實現(xiàn)Execute()方法,負責(zé)調(diào)用接收考的相應(yīng)操作。Execute()方法通常叫做執(zhí)行方法。
客戶(Client)角色:創(chuàng)建了一個具體命令(ConcreteCommand)對象并確定其接收者。
請求者(Invoker)角色:負責(zé)調(diào)用命令對象執(zhí)行請求,相關(guān)的方法叫做行動方法。
接收者(Receiver)角色:負責(zé)具體實施和執(zhí)行一個請求。任何一個類都可以成為接收者,實施和執(zhí)行請求的方法叫做行動方法。
四、命令模式的優(yōu)點
命令模式的優(yōu)點:
1、命令模式把請求一個操作的對象與知道怎么執(zhí)行一個操作的對象分離開。
2、命令類與其他任何別的類一樣,可以修改和推廣。
3、可以把命令對象聚合在一起,合成為合成命令。
4、可以很容易的加入新的命令類。
命令模式的缺點:可能會導(dǎo)致某些系統(tǒng)有過多的具體命令類。
五、命令模式適用場景
1、抽象出待執(zhí)行的動作以參數(shù)化對象。Command模式是回調(diào)機制的一個面向?qū)ο蟮奶娲贰?br />
2、在不同的時刻指定、排列和執(zhí)行請求。
3、支持取消操作。
4、支持修改日志。
5、用構(gòu)建在原語操作上的高層操作構(gòu)造一個系統(tǒng)。Command模式提供了對事務(wù)進行建模的方法。Command有一個公共的接口,使得你可以用同一種方式調(diào)用所有的事務(wù)。同時使用該模式也易于添加新事務(wù)以擴展系統(tǒng)。
六、命令模式與其它模式
合成模式(composite模式):Composite模式可被實現(xiàn)宏命令
原型模式(prototype模式):如果命令類帶有clone(或在之前的文章中提到的copy方法)方法,命令就可以被復(fù)制。在命令模式支持多次取消操作時可能需要用到此模式,以復(fù)制當(dāng)前狀態(tài)的Command對象
七、命令模式PHP示例
<?php /** * 命令角色 */ interface Command { /** * 執(zhí)行方法 */ public function execute(); } /** * 具體命令角色 */ class ConcreteCommand implements Command { private $_receiver; public function __construct(Receiver $receiver) { $this->_receiver = $receiver; } /** * 執(zhí)行方法 */ 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(); ?>
八、命令模式協(xié)作
1、Client創(chuàng)建一個ConcreteCommand對象并指定它的Receiver對象
2、某Invoker對象存儲該ConcreteCommand對象
3、該Invoker通過調(diào)用Command對象的execute操作來提交一個請求。若該命令是可撤消的,ConcreteCommand就在執(zhí)行execute操作之前存儲當(dāng)前狀態(tài)以用于取消命令。
4、ConcreteCommand對象對調(diào)用它的Receiver的一些操作以執(zhí)行該請求。
九、宏命令
在這里,我們以一個簡單的增加和粘貼功能為例,將這兩個命令組成一個宏命令。
我們可以新建復(fù)制命令和粘貼命令,然后將其添加到宏命令中去。
如下所示代碼:
<?php /** * 命令角色 */ interface Command { /** * 執(zhí)行方法 */ 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; } /** * 執(zhí)行方法 */ public function execute() { $this->_receiver->copy(); } } /** * 具體拷貝命令角色 */ class PasteCommand implements Command { private $_receiver; public function __construct(Receiver $receiver) { $this->_receiver = $receiver; } /** * 執(zhí)行方法 */ public function execute() { $this->_receiver->paste(); } } /** * 接收者角色 */ class Receiver { /* 接收者名稱 */ private $_name; public function __construct($name) { $this->_name = $name; } /** * 復(fù)制方法 */ 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實現(xiàn)命令模式的代碼,還有一些關(guān)于命令模式的概念區(qū)分,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
php使用explode()函數(shù)將字符串拆分成數(shù)組的方法
這篇文章主要介紹了php使用explode()函數(shù)將字符串拆分成數(shù)組的方法,具有一定參考借鑒價值,需要的朋友可以參考下2015-02-02WordPress中用于檢索模版的相關(guān)PHP函數(shù)使用解析
這篇文章主要介紹了WordPress中用于檢索模版的相關(guān)PHP函數(shù)使用解析,包括索模板的函數(shù)的使用,要的朋友可以參考下2015-12-12php數(shù)據(jù)結(jié)構(gòu)與算法(PHP描述) 查找與二分法查找
php數(shù)據(jù)結(jié)構(gòu)與算法(PHP描述) 查找與二分法查找,需要的朋友可以參考下2012-06-06