[設計模式] javascript 之 命令模式

模式定義:編程

[定義]: 將一個請求封裝成一個對象,使得你用不一樣的請求把客戶端參數化,對請求排隊或者記錄請求日誌,能夠提供命令的撤銷和恢復功能。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 = ....

以上的語句特色:對象

  1. 一個請求只執行一個操做,每一個操做都伴隨一個具體的命令實現類;
  2. 由於具體的執行操做是在具體的接收着進行的,請求經過執行命令類才能執行到,所以它又具備委託(callback)的特色;

這樣設計的優缺點: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再執行相應的方法;

相關文章
相關標籤/搜索