模式定義:編程
[定義]: 將一個請求封裝成一個對象,使得你用不一樣的請求把客戶端參數化,對請求排隊或者記錄請求日誌,能夠提供命令的撤銷和恢復功能。this
組成: 調用者(Invoker),命令請求(Command,包括接口或抽象,以及實現,待對象化),接收者(實現者 Receiver,包括抽象接口,及實現),三個角色;spa
過程: 命令經過請求者發送給接收者來實現; 命令委託間接通知,再執行實現;prototype
理解: 請求可能會有多個,接收者可能也有多個,可能一個請求一個執行者,也可能多個請求一個執行者; 請求以及執行者是耦合的,客戶端能夠調用時,能夠給請求指定個執行者,以及執行方法; 這個就能夠達到請求參數化的效果,並能夠對請求進行排隊列等等操做;設計
所以它能夠經過如下方式來表達 請求者與接收者 的耦合,以及請求者經過發送命令,沒必要具體知識執行了什麼的效果;日誌
var invoker = new Invoker(concreteCommand1); invoker.execute(); invoker = new Invoker(concreteCommand2); invoker.execute();
或者:code
var invoker = new Invoker(); invoker.setCommand(concreteCommand1); invoker.execute(); var invoker2 = ....
以上的語句特色:對象
這樣設計的優缺點:blog
這裏要說到兩個設計原則:開閉原則,以及依賴倒置原則;繼承
開閉原則:就是對擴展是開放的,對於修改是關閉的;它是面向對象裏最從新的原則之一,是提升代碼可複用的原則;
現實世界中,存在在衆多行爲操做相似的事物,好比不同的人,都擁有吃飯,看書,運動的能力;
但每一個人表現出來的行爲動做可能,喜愛多是是不同;但咱們將每一個人各類動做(方法)整合在一個大類裏實現時,
第一會出現不少相似重複的方法,第二整個類會很大,很雜,很差維護;當僅是其中一個的喜愛出現不同時,修改可能還會影響到其餘人的操做;
所以在面向對象的思想裏,推薦對每一個類基於抽象進行編程,無論是繼承抽象,或是實現接口;這樣出現需對新的相似事物進行擴展時,只需基於抽象進行擴展;
依賴倒置原則:
1. 抽象不能依束於具體實現,具體實現要依賴於抽象; 簡單就是編程要針對抽象或接口編程,不要針對具體實現編輯;
2. 開閉原則是整個面向對象編輯的基礎,也是終級目標;依賴倒置原則是實現開閉原則的一個基礎;
3. 想對於具體實現,抽象或接口會比較穩定,針對接口或抽象進行編輯,提升開發的穩定性,不會由具體實現由於具體狀況的多變不穩定性,而可能須要常常修改;
針對穩定的抽象進行編輯,多變的具體實現針對抽象實現,提升內聚低耦合的效果,具體獨立,才能夠更好的針對變化進行擴展,而不是修改;
應用場景:
a. 好比老闆讓員工執行某項任務; (老闆: Invoker,員工: Receiver,請求命令:command)
老闆能夠隨便指定一個員工(員工多個),員工實現手段不同,老闆沒必要知道;
請求命令,工做任務也有不少種... (每一個任務,也都各自的實現手段跟組成,多個方法)
b. 好比 經過搖控機控制多種設備的開機關機等; (手是Invoker,按鈕是Receiver, 命令是設備的開關機)
搖控機上多組按鈕組合(電燈的開跟關,電視機,以及電風扇的)
手能夠點擊任意一個按鈕;
命令這裏就是開或關;
源碼實現:
//接收者 function Worker() { } Worker.prototype.doMethod = function() { //do somethong; } //命令 functiom Command(worker) { this.worker = worker; } Command.prototype.doCommand = function() { // do command this.worker.doMethod(); } //調用者 function Invoker(command) { this.doWork = function() { command.doCommand } } ///////////////////////////////////////////////////////// //客戶端調用(工做具體工做實現) var workerA = new Worker(); var commandA = new Command(workerA); var invoker = new Invoker(commandA); invoker.doWork();
換成JAVA的寫法,即Worker一個接口或抽象類,兩個具體的工人類(Worker實現),Command爲接口或抽象,一兩個具體的實現;
調用處,針對接口或抽象進行調用具體的請求以及接收者,調用者Invoker再執行相應的方法;