电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

PHP設計模式之命令模式示例詳解

瀏覽:49日期:2022-09-08 13:37:31
前言

命令模式,也稱為動作或者事務模式,很多教材會用飯館來舉例。作為顧客的我們是命令的下達者,服務員是這個命令的接收者,菜單是這個實際的命令,而廚師是這個命令的執行者。那么,這個模式解決了什么呢?當你要修改菜單的時候,只需要和服務員說就好了,她會轉達給廚師,也就是說,我們實現了顧客和廚師的解耦。也就是調用者與實現者的解耦。當然,很多設計模式可以做到這一點,但是命令模式能夠做到的是讓一個命令接收者實現多個命令(服務員下單、拿酒水、上菜),或者把一條命令轉達給多個實現者(熱菜廚師、涼菜廚師、主食師傅)。這才是命令模式真正發揮的地方!!

Gof類圖及解釋

GoF定義:將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日志,以及支持可撤消的操作

GoF類圖

PHP設計模式之命令模式示例詳解

代碼實現

class Invoker{ public $command; public function __construct($command) { $this->command = $command; } public function exec() { $this->command->execute(); }}

首先我們定義一個命令的接收者,或者說是命令的請求者更恰當。類圖中的英文定義這個單詞是“祈求者”。也就是由它來發起和操作命令。

abstract class Command{ protected $receiver; public function __construct(Receiver $receiver) { $this->receiver = $receiver; } abstract public function execute();}class ConcreteCommand extends Command{ public function execute() { $this->receiver->action(); }}

接下來是命令,也就是我們的“菜單”。這個命令的作用是為了定義真正的執行者是誰。

class Receiver{ public $name; public function __construct($name) { $this->name = $name; } public function action() { echo $this->name . ’命令執行了!’, PHP_EOL; }}

接管者,也就是執行者,真正去執行命令的人。

// 準備執行者$receiverA = new Receiver(’A’);// 準備命令$command = new ConcreteCommand($receiverA);// 請求者$invoker = new Invoker($command);$invoker->exec();

客戶端的調用,我們要聯系好執行者也就是挑有好廚子的飯館(Receiver),然后準備好命令也就是菜單(Command),最后交給服務員(Invoker)。

其實這個飯店的例子已經非常清晰了,對于命令模式真是完美的解析

那說好的可以下多份訂單或者給多個廚師呢?別急,下面的代碼幫助我們解決這個問題

完整代碼: https://github.com/zhangyue0503/designpatterns-php/blob/master/09.command/source/command.php

<?phpclass Invoker{ private $command = []; public function setCommand(Command $command) { $this->command[] = $command; } public function exec() { if(count($this->command) > 0){ foreach ($this->command as $command) { $command->execute(); } } } public function undo() { if(count($this->command) > 0){ foreach ($this->command as $command) { $command->undo(); } } }}abstract class Command{ protected $receiver; protected $state; protected $name; public function __construct(Receiver $receiver, $name) { $this->receiver = $receiver; $this->name = $name; } abstract public function execute();}class ConcreteCommand extends Command{ public function execute() { if (!$this->state || $this->state == 2) { $this->receiver->action(); $this->state = 1; } else { echo $this->name . ’命令正在執行,無法再次執行了!’, PHP_EOL; } } public function undo() { if ($this->state == 1) { $this->receiver->undo(); $this->state = 2; } else { echo $this->name . ’命令未執行,無法撤銷了!’, PHP_EOL; } }}class Receiver{ public $name; public function __construct($name) { $this->name = $name; } public function action() { echo $this->name . ’命令執行了!’, PHP_EOL; } public function undo() { echo $this->name . ’命令撤銷了!’, PHP_EOL; }}// 準備執行者$receiverA = new Receiver(’A’);$receiverB = new Receiver(’B’);$receiverC = new Receiver(’C’);// 準備命令$commandOne = new ConcreteCommand($receiverA, ’A’);$commandTwo = new ConcreteCommand($receiverA, ’B’);$commandThree = new ConcreteCommand($receiverA, ’C’);// 請求者$invoker = new Invoker();$invoker->setCommand($commandOne);$invoker->setCommand($commandTwo);$invoker->setCommand($commandThree);$invoker->exec();$invoker->undo();// 新加一個單獨的執行者,只執行一個命令$invokerA = new Invoker();$invokerA->setCommand($commandOne);$invokerA->exec();// 命令A已經執行了,再次執行全部的命令執行者,A命令的state判斷無法生效$invoker->exec(); 這一次我們一次性解決了多個訂單、多位廚師的問題,并且還順便解決了如果下錯命令了,進行撤銷的問題 可以看出來,命令模式將調用操作的對象與知道如何實現該操作的對象實現了解耦 這種多命令多執行者的實現,有點像 組合模式 的實現 在這種情況下,增加新的命令,即不會影響執行者,也不會影響客戶。當有新的客戶需要新的命令時,只需要增加命令和請求者即可。即使有修改的需求,也只是修改請求者。 Laravel框架的事件調度機制中,除了觀察者模式外,也很明顯的能看出命令模式的影子

我們的手機工廠和餐廳其實并沒有什么兩樣,當我們需要代工廠來制作手機時,也是先下訂單,這個訂單就可以看做是命令。在這個訂單中,我們會規定好需要用到的配件,什么型號的CPU,什么型號的內存,預裝什么系統之類的。然后代工廠的工人們就會根據這個訂單來進行生產。在這個過程中,我不用關心是某一個工人還是一群工人來執行這個訂單,我只需要將這個訂單交給和我們對接的人就可以了,然后只管等著手機生產出來進行驗收咯!!

完整代碼: https://github.com/zhangyue0503/designpatterns-php/blob/master/09.command/source/command-up.php

實例

短信功能又回來了,我們發現除了工廠模式外,命令模式貌似也是一種不錯的實現方式哦。在這里,我們依然是使用那幾個短信和推送的接口,話不多說,我們用命令模式再來實現一個吧。當然,有興趣的朋友可以接著實現我們的短信撤回功能哈,想想上面的命令取消是怎么實現的。

短信發送類圖

PHP設計模式之命令模式示例詳解

完整源碼: https://github.com/zhangyue0503/designpatterns-php/blob/master/09.command/source/command-message.php

<?phpclass SendMsg{ private $command = []; public function setCommand(Command $command) { $this->command[] = $command; } public function send($msg) { foreach ($this->command as $command) { $command->execute($msg); } }}abstract class Command{ protected $receiver = []; public function setReceiver($receiver) { $this->receiver[] = $receiver; } abstract public function execute($msg);}class SendAliYun extends Command{ public function execute($msg) { foreach ($this->receiver as $receiver) { $receiver->action($msg); } }}class SendJiGuang extends Command{ public function execute($msg) { foreach ($this->receiver as $receiver) { $receiver->action($msg); } }}class SendAliYunMsg{ public function action($msg) { echo ’【阿X云短信】發送:’ . $msg, PHP_EOL; }}class SendAliYunPush{ public function action($msg) { echo ’【阿X云推送】發送:’ . $msg, PHP_EOL; }}class SendJiGuangMsg{ public function action($msg) { echo ’【極X短信】發送:’ . $msg, PHP_EOL; }}class SendJiGuangPush{ public function action($msg) { echo ’【極X推送】發送:’ . $msg, PHP_EOL; }}$aliMsg = new SendAliYunMsg();$aliPush = new SendAliYunPush();$jgMsg = new SendJiGuangMsg();$jgPush = new SendJiGuangPush();$sendAliYun = new SendAliYun();$sendAliYun->setReceiver($aliMsg);$sendAliYun->setReceiver($aliPush);$sendJiGuang = new SendJiGuang();$sendAliYun->setReceiver($jgMsg);$sendAliYun->setReceiver($jgPush);$sendMsg = new SendMsg();$sendMsg->setCommand($sendAliYun);$sendMsg->setCommand($sendJiGuang);$sendMsg->send(’這次要搞個大活動,快來注冊吧!!’);說明 在這個例子中,依然是多命令多執行者的模式 可以將這個例子與抽象工廠進行對比,同樣的功能使用不同的設計模式來實現,但是要注意的是,抽象工廠更多的是為了生產對象返回對象,而命令模式則是一種行為的選擇 我們可以看出命令模式非常適合形成命令隊列,多命令讓命令可以一條一條執行下去 它允許接收的一方決定是否要否決請求,Receiver做為實現者擁有更多的話語權

到此這篇關于PHP設計模式之命令模式的文章就介紹到這了,更多相關PHP設計模式之命令模式內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: PHP
相關文章:
主站蜘蛛池模板: 武汉天安盾电子设备有限公司 - 安盾安检,武汉安检门,武汉安检机,武汉金属探测器,武汉测温安检门,武汉X光行李安检机,武汉防爆罐,武汉车底安全检查,武汉液体探测仪,武汉安检防爆设备 | 药品冷藏箱厂家_低温冰箱_洁净工作台-济南欧莱博电子商务有限公司官网 | 安规_综合测试仪,电器安全性能综合测试仪,低压母线槽安规综合测试仪-青岛合众电子有限公司 | 不锈钢丸厂家,铝丸,铸钢丸-淄博智源铸造材料有限公司 | 沟盖板_复合沟盖板厂_电力盖板_树脂雨水篦子-淄博拜斯特 | 恒温水槽与水浴锅-上海熙浩实业有限公司 | 石英粉,滑石粉厂家,山东滑石粉-莱州市向阳滑石粉有限公司 | 郑州宣传片拍摄-TVC广告片拍摄-微电影短视频制作-河南优柿文化传媒有限公司 | 液氮罐_液氮容器_自增压液氮罐-北京君方科仪科技发展有限公司 | 二维运动混料机,加热型混料机,干粉混料机-南京腾阳干燥设备厂 | C形臂_动态平板DR_动态平板胃肠机生产厂家制造商-普爱医疗 | 禹城彩钢厂_钢结构板房_彩钢复合板-禹城泰瑞彩钢复合板加工厂 | 游动电流仪-流通式浊度分析仪-杰普仪器(上海)有限公司 | uv固化机-丝印uv机-工业烤箱-五金蚀刻机-分拣输送机 - 保定市丰辉机械设备制造有限公司 | 新能源汽车电池软连接,铜铝复合膜柔性连接,电力母排-容发智能科技(无锡)有限公司 | 接地电阻测试仪[厂家直销]_电缆故障测试仪[精准定位]_耐压测试仪-武汉南电至诚电力设备 | 科威信洗净科技,碳氢清洗机,超声波清洗机,真空碳氢清洗机 | 诗词大全-古诗名句 - 古诗词赏析 | 柴油机_柴油发电机_厂家_品牌-江苏卡得城仕发动机有限公司 | 江苏远邦专注皮带秤,高精度皮带秤,电子皮带秤研发生产 | 旋片真空泵_真空泵_水环真空泵_真空机组-深圳恒才机电设备有限公司 | GEDORE扭力螺丝刀-GORDON防静电刷-CHEMTRONICS吸锡线-上海卓君电子有限公司 | 神马影院-实时更新秒播 | 自动化展_机器人展_机床展_工业互联网展_广东佛山工博会 | pbt头梳丝_牙刷丝_尼龙毛刷丝_PP塑料纤维合成毛丝定制厂_广州明旺 | 防火门-专业生产甲级不锈钢钢质防火门厂家资质齐全-广东恒磊安防设备有限公司 | 硫酸亚铁-聚合硫酸铁-除氟除磷剂-复合碳源-污水处理药剂厂家—长隆科技 | 玻纤土工格栅_钢塑格栅_PP焊接_单双向塑料土工格栅_复合防裂布厂家_山东大庚工程材料科技有限公司 | KBX-220倾斜开关|KBW-220P/L跑偏开关|拉绳开关|DHJY-I隔爆打滑开关|溜槽堵塞开关|欠速开关|声光报警器-山东卓信有限公司 | 焊接烟尘净化器__焊烟除尘设备_打磨工作台_喷漆废气治理设备 -催化燃烧设备 _天津路博蓝天环保科技有限公司 | 塑料熔指仪-塑料熔融指数仪-熔体流动速率试验机-广东宏拓仪器科技有限公司 | vr安全体验馆|交通安全|工地安全|禁毒|消防|安全教育体验馆|安全体验教室-贝森德(深圳)科技 | 不发火防静电金属骨料_无机磨石_水泥自流平_修补砂浆厂家「圣威特」 | 山东钢衬塑罐_管道_反应釜厂家-淄博富邦滚塑防腐设备科技有限公司 | LHH药品稳定性试验箱-BPS系列恒温恒湿箱-意大利超低温冰箱-上海一恒科学仪器有限公司 | 通辽信息港 - 免费发布房产、招聘、求职、二手、商铺等信息 www.tlxxg.net | 上海新光明泵业制造有限公司-电动隔膜泵,气动隔膜泵,卧式|立式离心泵厂家 | 东莞喷砂机-喷砂机-喷砂机配件-喷砂器材-喷砂加工-东莞市协帆喷砂机械设备有限公司 | 定坤静电科技静电消除器厂家-除静电设备 | 电机铸铝配件_汽车压铸铝合金件_发动机压铸件_青岛颖圣赫机械有限公司 | UV固化机_UVLED光固化机_UV干燥机生产厂家-上海冠顶公司专业生产UV固化机设备 |