本文實例講述了PHP命令Command模式用法。分享給大家供大家參考,具體如下:
命令Command模式是GOF23種模式中的一種,是一種行為模式。這種模式很難理解?!对O計模式》一書中對它語焉不詳。而網(wǎng)上的一些文章對其的解釋也是錯誤的。實際上,命令模式并不是那么神秘。
命令模式的理解,關鍵有2點:
1. 使用接口。通常命令模式的接口中只有一個方法。 實現(xiàn)類的方法有不同的功能,覆蓋接口中的方法。在面向對象編程中,大量使用if…else…
,或者switch…case…
這樣的條件選擇語句是“最差實踐”。通常這類代碼,意味著有重構的余地。命令模式就是干掉條件選擇語句的利器。
首先提供一個接口:
public interface Command { public void execute(); }
然后提供這個接口的實現(xiàn)類。每一個實現(xiàn)類的方法就是if…else…
的一個代碼塊中的代碼。這樣,調用方直接把一個具體類的實例傳進來即可。如:
Public void test(Command para){ Para.execute(); }
不需要再判斷出現(xiàn)了哪種情況,應該執(zhí)行哪一段代碼。一切的問題都由調用方處理。
如果不使用命令模式,那么如果情況逐步增多,如,從原來的2種,增加到20種,那么方法中的判斷就會從1次增加到19次。而使用命令模式,僅僅調用方需要從2個實現(xiàn)類增加到20個實現(xiàn)類即可。上面的test方法根本不需要做任何改變。
2. 主要的用途是,使用參數(shù)回調模式。
最主要使用命令模式的方式是使用參數(shù)回調模式。命令接口作為方法的參數(shù)傳遞進來。然后,在方法體內回調該接口。
當然,命令模式還可以使用其他方式來使用。不一定非用參數(shù)回調模式。
了解完這些之后,可以看一下下面的程序例子。
?php /** * 命令模式 * * 將一個請求封裝為一個對象從而使你可用不同的請求對客戶進行參數(shù)化,對請求排除或記錄請求日志,以及支持可取消的操作 */ // 命令接口 interface Command { public function execute(); } class Invoker { private $_command = array(); public function setCommand($command) { $this->_command[] = $command; } public function executeCommand() { foreach($this->_command as $command) { $command->execute(); } } public function removeCommand($command) { $key = array_search($command, $this->_command); if($key !== false) { unset($this->_command[$key]); } } } // 命令接受者 class Receiver { private $_name = null; public function __construct($name) { $this->_name = $name; } public function action() { echo $this->_name." 執(zhí)行攻擊命令(action)br />"; } public function action1() { echo $this->_name." 執(zhí)行防御命令(action1)br/>"; } } // 具體的命令 class ConcreteCommand implements Command { private $_receiver; public function __construct($receiver) { $this->_receiver = $receiver; } public function execute() { $this->_receiver->action(); } } // 具體命令1 class ConcreteCommand1 implements Command { private $_receiver; public function __construct($receiver) { $this->_receiver = $receiver; } public function execute() { $this->_receiver->action1(); } } // 具體命令2 class ConcreteCommand2 implements Command { private $_receiver; public function __construct($receiver) { $this->_receiver = $receiver; } public function execute() { $this->_receiver->action(); $this->_receiver->action1(); } } $objRecevier = new Receiver("小狗"); $objRecevier1 = new Receiver("刺蛇"); $objRecevier2 = new Receiver("雷獸"); $objCommand = new ConcreteCommand($objRecevier); $objCommand1 = new ConcreteCommand1($objRecevier); $objCommand2 = new ConcreteCommand($objRecevier1); $objCommand3 = new ConcreteCommand1($objRecevier1); $objCommand4 = new ConcreteCommand2($objRecevier2); // 使用 Recevier的兩個方法 $objInvoker = new Invoker(); $objInvoker->setCommand($objCommand); $objInvoker->setCommand($objCommand1); $objInvoker->executeCommand(); $objInvoker->removeCommand($objCommand1); $objInvoker->executeCommand(); $objInvoker->setCommand($objCommand2); $objInvoker->setCommand($objCommand3); $objInvoker->setCommand($objCommand4); $objInvoker->executeCommand(); ?>
程序運行結果:
小狗 執(zhí)行攻擊命令(action)
小狗 執(zhí)行防御命令(action1)
小狗 執(zhí)行攻擊命令(action)
小狗 執(zhí)行攻擊命令(action)
刺蛇 執(zhí)行攻擊命令(action)
刺蛇 執(zhí)行防御命令(action1)
雷獸 執(zhí)行攻擊命令(action)
雷獸 執(zhí)行防御命令(action1)
命令模式的核心思想是,帶有某個方法的具體類的實例,作為接口傳給使用方。對象的具體類型信息消失。在使用方代碼中拿到這個接口后調用這個接口的方法。
具體的執(zhí)行效果,取決的命令發(fā)起人提供的對象是哪一個實現(xiàn)類的。這給了命令發(fā)起人完全的控制能力,而使用方代碼不關心具體的命令類和方法。同時也使條件判斷語句成為多余。
簡單嗎?命令模式其實就是這么簡單。
其實,GOF的23個設計模式中,好幾個模式使用了相同的技巧來實現(xiàn)。GOF對模式的劃分,是根據(jù)目的來的,而不是技巧來的。因此,Command模式和策略模式等其實使用的技法是一樣的。 上回和一個同事聊技術。他的背景是Windows C++和Windows驅動開發(fā)。 他說,他不知道什么設計模式。他覺得最有用的就是回調函數(shù)。Command模式也是使用回調函數(shù)。java沒有函數(shù)指針,java中一切都是類和類的實例。因此,就需要使用一個只有一個函數(shù)的接口,它的實例表示函數(shù)指針。其實是一回事。
設計模式是比較低層次的設計思想。在更高層次上,還有更加宏觀的一些設計技巧。 Bob大叔的一本書不錯,忘記名字了。 《Unix編程藝術》也不錯,都是講更高層次上的設計的。
更多關于PHP相關內容感興趣的讀者可查看本站專題:《php面向對象程序設計入門教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運算與運算符用法總結》、《php字符串(string)用法總結》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對大家PHP程序設計有所幫助。