PHP命令Command模式用法實(shí)例分析
本文實(shí)例講述了PHP命令Command模式用法。分享給大家供大家參考,具體如下:
命令Command模式是GOF23種模式中的一種,是一種行為模式。這種模式很難理解。《設(shè)計(jì)模式》一書中對(duì)它語焉不詳。而網(wǎng)上的一些文章對(duì)其的解釋也是錯(cuò)誤的。實(shí)際上,命令模式并不是那么神秘。
命令模式的理解,關(guān)鍵有2點(diǎn):
1. 使用接口。通常命令模式的接口中只有一個(gè)方法。 實(shí)現(xiàn)類的方法有不同的功能,覆蓋接口中的方法。在面向?qū)ο缶幊讨?,大量使?code>if…else…,或者switch…case…這樣的條件選擇語句是“最差實(shí)踐”。通常這類代碼,意味著有重構(gòu)的余地。命令模式就是干掉條件選擇語句的利器。
首先提供一個(gè)接口:
public interface Command {
public void execute();
}
然后提供這個(gè)接口的實(shí)現(xiàn)類。每一個(gè)實(shí)現(xiàn)類的方法就是if…else…的一個(gè)代碼塊中的代碼。這樣,調(diào)用方直接把一個(gè)具體類的實(shí)例傳進(jìn)來即可。如:
Public void test(Command para){
Para.execute();
}
不需要再判斷出現(xiàn)了哪種情況,應(yīng)該執(zhí)行哪一段代碼。一切的問題都由調(diào)用方處理。
如果不使用命令模式,那么如果情況逐步增多,如,從原來的2種,增加到20種,那么方法中的判斷就會(huì)從1次增加到19次。而使用命令模式,僅僅調(diào)用方需要從2個(gè)實(shí)現(xiàn)類增加到20個(gè)實(shí)現(xiàn)類即可。上面的test方法根本不需要做任何改變。
2. 主要的用途是,使用參數(shù)回調(diào)模式。
最主要使用命令模式的方式是使用參數(shù)回調(diào)模式。命令接口作為方法的參數(shù)傳遞進(jìn)來。然后,在方法體內(nèi)回調(diào)該接口。
當(dāng)然,命令模式還可以使用其他方式來使用。不一定非用參數(shù)回調(diào)模式。
了解完這些之后,可以看一下下面的程序例子。
<?php
/**
* 命令模式
*
* 將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化,對(duì)請(qǐng)求排除或記錄請(qǐng)求日志,以及支持可取消的操作
*/
// 命令接口
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的兩個(gè)方法
$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();
?>
程序運(yùn)行結(jié)果:
小狗 執(zhí)行攻擊命令(action)
小狗 執(zhí)行防御命令(action1)
小狗 執(zhí)行攻擊命令(action)
小狗 執(zhí)行攻擊命令(action)
刺蛇 執(zhí)行攻擊命令(action)
刺蛇 執(zhí)行防御命令(action1)
雷獸 執(zhí)行攻擊命令(action)
雷獸 執(zhí)行防御命令(action1)
命令模式的核心思想是,帶有某個(gè)方法的具體類的實(shí)例,作為接口傳給使用方。對(duì)象的具體類型信息消失。在使用方代碼中拿到這個(gè)接口后調(diào)用這個(gè)接口的方法。
具體的執(zhí)行效果,取決的命令發(fā)起人提供的對(duì)象是哪一個(gè)實(shí)現(xiàn)類的。這給了命令發(fā)起人完全的控制能力,而使用方代碼不關(guān)心具體的命令類和方法。同時(shí)也使條件判斷語句成為多余。
簡(jiǎn)單嗎?命令模式其實(shí)就是這么簡(jiǎn)單。
其實(shí),GOF的23個(gè)設(shè)計(jì)模式中,好幾個(gè)模式使用了相同的技巧來實(shí)現(xiàn)。GOF對(duì)模式的劃分,是根據(jù)目的來的,而不是技巧來的。因此,Command模式和策略模式等其實(shí)使用的技法是一樣的。 上回和一個(gè)同事聊技術(shù)。他的背景是Windows C++和Windows驅(qū)動(dòng)開發(fā)。 他說,他不知道什么設(shè)計(jì)模式。他覺得最有用的就是回調(diào)函數(shù)。Command模式也是使用回調(diào)函數(shù)。java沒有函數(shù)指針,java中一切都是類和類的實(shí)例。因此,就需要使用一個(gè)只有一個(gè)函數(shù)的接口,它的實(shí)例表示函數(shù)指針。其實(shí)是一回事。
設(shè)計(jì)模式是比較低層次的設(shè)計(jì)思想。在更高層次上,還有更加宏觀的一些設(shè)計(jì)技巧。 Bob大叔的一本書不錯(cuò),忘記名字了。 《Unix編程藝術(shù)》也不錯(cuò),都是講更高層次上的設(shè)計(jì)的。
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
相關(guān)文章
PHP編碼規(guī)范-php coding standard
標(biāo)準(zhǔn)化問題在某些方面上讓每個(gè)人頭痛,讓人人都覺得大家處于同樣的境地。這有助于讓這些建議在許多的項(xiàng)目中不斷演進(jìn),許多公司花費(fèi)了許多星期逐子字逐句的進(jìn)行爭(zhēng)論。2007-03-03
php獲取遠(yuǎn)程圖片的兩種 CURL方式和sockets方式獲取遠(yuǎn)程圖片
php獲取遠(yuǎn)程圖片的兩種:CURL方式和sockets方式獲取遠(yuǎn)程圖片,需要的朋友可以參考下。2011-11-11
PHP封裝類似thinkphp連貫操作數(shù)據(jù)庫Db類與簡(jiǎn)單應(yīng)用示例
這篇文章主要介紹了PHP封裝類似thinkphp連貫操作數(shù)據(jù)庫Db類與簡(jiǎn)單應(yīng)用,涉及php基于mysqli的數(shù)據(jù)庫連接、增刪改查、異常處理等相關(guān)操作技巧,需要的朋友可以參考下2019-05-05
PHP函數(shù)utf8轉(zhuǎn)gb2312編碼
PHP函數(shù)utf8轉(zhuǎn)gb2312編碼...2006-12-12
PHP連接Access數(shù)據(jù)庫的方法小結(jié)
有時(shí)候我們?cè)陂_發(fā)一些小程序或簡(jiǎn)單功能的管理系統(tǒng),又沒有mysql數(shù)據(jù)庫的情況下,就可以使用access了,這里介紹下鏈接方法2013-06-06
解析PHP自帶的進(jìn)位制之間的轉(zhuǎn)換函數(shù)
本篇文章是對(duì)PHP自帶的進(jìn)位制之間的轉(zhuǎn)換函數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
php將12小時(shí)制轉(zhuǎn)換成24小時(shí)制的方法
這篇文章主要介紹了php將12小時(shí)制轉(zhuǎn)換成24小時(shí)制的方法,涉及php時(shí)間操作的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03
thinkphp多表查詢兩表有重復(fù)相同字段的完美解決方法
下面小編就為大家?guī)硪黄猼hinkphp多表查詢兩表有重復(fù)相同字段的完美解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09

