學(xué)習(xí)php設(shè)計(jì)模式 php實(shí)現(xiàn)命令模式(command)
一、意圖
將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使用你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤消的操作。
可變的方面是:何時(shí),怎樣滿足一個(gè)請(qǐng)求
命令模式是對(duì)命令的封裝。命令模式把發(fā)出命令的責(zé)任和執(zhí)行命令的責(zé)任分割開(kāi),委派給不同的對(duì)象。
請(qǐng)求的一方發(fā)出請(qǐng)求要求執(zhí)行一個(gè)操作;接收的一方收到請(qǐng)求,并執(zhí)行操作。命令模式允許請(qǐng)求的一方和接收的一方獨(dú)立開(kāi)來(lái),使得請(qǐng)求的一方不必知道接收請(qǐng)求的一方的接口,更不必知道請(qǐng)求是怎么被接收,以及操作是否被執(zhí)行、何時(shí)被執(zhí)行,以及是怎么被執(zhí)行的。
二、命令模式結(jié)構(gòu)圖

三、命令模式中主要角色
命令(Command)角色:聲明了一個(gè)給所有具體命令類的抽象接口。這是一個(gè)抽象角色。
具體命令(ConcreteCommand)角色:定義一個(gè)接受者和行為之間的弱耦合;實(shí)現(xiàn)Execute()方法,負(fù)責(zé)調(diào)用接收考的相應(yīng)操作。Execute()方法通常叫做執(zhí)行方法。
客戶(Client)角色:創(chuàng)建了一個(gè)具體命令(ConcreteCommand)對(duì)象并確定其接收者。
請(qǐng)求者(Invoker)角色:負(fù)責(zé)調(diào)用命令對(duì)象執(zhí)行請(qǐng)求,相關(guān)的方法叫做行動(dòng)方法。
接收者(Receiver)角色:負(fù)責(zé)具體實(shí)施和執(zhí)行一個(gè)請(qǐng)求。任何一個(gè)類都可以成為接收者,實(shí)施和執(zhí)行請(qǐng)求的方法叫做行動(dòng)方法。
四、命令模式的優(yōu)點(diǎn)
命令模式的優(yōu)點(diǎn):
1、命令模式把請(qǐng)求一個(gè)操作的對(duì)象與知道怎么執(zhí)行一個(gè)操作的對(duì)象分離開(kāi)。
2、命令類與其他任何別的類一樣,可以修改和推廣。
3、可以把命令對(duì)象聚合在一起,合成為合成命令。
4、可以很容易的加入新的命令類。
命令模式的缺點(diǎn):可能會(huì)導(dǎo)致某些系統(tǒng)有過(guò)多的具體命令類。
五、命令模式適用場(chǎng)景
1、抽象出待執(zhí)行的動(dòng)作以參數(shù)化對(duì)象。Command模式是回調(diào)機(jī)制的一個(gè)面向?qū)ο蟮奶娲贰?br />
2、在不同的時(shí)刻指定、排列和執(zhí)行請(qǐng)求。
3、支持取消操作。
4、支持修改日志。
5、用構(gòu)建在原語(yǔ)操作上的高層操作構(gòu)造一個(gè)系統(tǒng)。Command模式提供了對(duì)事務(wù)進(jìn)行建模的方法。Command有一個(gè)公共的接口,使得你可以用同一種方式調(diào)用所有的事務(wù)。同時(shí)使用該模式也易于添加新事務(wù)以擴(kuò)展系統(tǒng)。
六、命令模式與其它模式
合成模式(composite模式):Composite模式可被實(shí)現(xiàn)宏命令
原型模式(prototype模式):如果命令類帶有clone(或在之前的文章中提到的copy方法)方法,命令就可以被復(fù)制。在命令模式支持多次取消操作時(shí)可能需要用到此模式,以復(fù)制當(dāng)前狀態(tài)的Command對(duì)象
七、命令模式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;
}
/**
* 行動(dòng)方法
*/
public function action() {
echo $this->_name, ' do action.<br />';
}
}
/**
* 請(qǐng)求者角色
*/
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)建一個(gè)ConcreteCommand對(duì)象并指定它的Receiver對(duì)象
2、某Invoker對(duì)象存儲(chǔ)該ConcreteCommand對(duì)象
3、該Invoker通過(guò)調(diào)用Command對(duì)象的execute操作來(lái)提交一個(gè)請(qǐng)求。若該命令是可撤消的,ConcreteCommand就在執(zhí)行execute操作之前存儲(chǔ)當(dāng)前狀態(tài)以用于取消命令。
4、ConcreteCommand對(duì)象對(duì)調(diào)用它的Receiver的一些操作以執(zhí)行該請(qǐng)求。
九、宏命令
在這里,我們以一個(gè)簡(jiǎn)單的增加和粘貼功能為例,將這兩個(gè)命令組成一個(gè)宏命令。
我們可以新建復(fù)制命令和粘貼命令,然后將其添加到宏命令中去。
如下所示代碼:
<?php
/**
* 命令角色
*/
interface Command {
/**
* 執(zhí)行方法
*/
public function execute();
}
/**
* 宏命令接口
*/
interface MacroCommand extends Command {
/**
* 宏命令聚集的管理方法,可以刪除一個(gè)成員命令
* @param Command $command
*/
public function remove(Command $command);
/**
* 宏命令聚集的管理方法,可以增加一個(gè)成員命令
* @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 />';
}
}
/**
* 請(qǐng)求者角色
*/
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實(shí)現(xiàn)命令模式的代碼,還有一些關(guān)于命令模式的概念區(qū)分,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
php使用explode()函數(shù)將字符串拆分成數(shù)組的方法
這篇文章主要介紹了php使用explode()函數(shù)將字符串拆分成數(shù)組的方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02
php+ajax實(shí)時(shí)輸入自動(dòng)搜索匹配的方法
這篇文章主要介紹了php+ajax實(shí)時(shí)輸入自動(dòng)搜索匹配的方法,實(shí)例分析了兩種實(shí)現(xiàn)方法,是非常實(shí)用的技巧,需要的朋友可以參考下2014-12-12
WordPress中用于檢索模版的相關(guān)PHP函數(shù)使用解析
這篇文章主要介紹了WordPress中用于檢索模版的相關(guān)PHP函數(shù)使用解析,包括索模板的函數(shù)的使用,要的朋友可以參考下2015-12-12
php數(shù)據(jù)結(jié)構(gòu)與算法(PHP描述) 查找與二分法查找
php數(shù)據(jù)結(jié)構(gòu)與算法(PHP描述) 查找與二分法查找,需要的朋友可以參考下2012-06-06
php約瑟夫問(wèn)題解決關(guān)于處死犯人的算法
這篇文章主要介紹了php約瑟夫問(wèn)題解決關(guān)于處死犯人的算法,實(shí)例分析了php關(guān)于約瑟夫問(wèn)題的實(shí)現(xiàn)與應(yīng)用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03

