鍍金池/ 教程/ HTML/ 設(shè)計(jì)模式之命令模式
代碼復(fù)用模式(避免篇)
S.O.L.I.D 五大原則之接口隔離原則 ISP
設(shè)計(jì)模式之狀態(tài)模式
JavaScript 核心(晉級(jí)高手必讀篇)
設(shè)計(jì)模式之建造者模式
JavaScript 與 DOM(上)——也適用于新手
設(shè)計(jì)模式之中介者模式
設(shè)計(jì)模式之裝飾者模式
設(shè)計(jì)模式之模板方法
設(shè)計(jì)模式之外觀模式
強(qiáng)大的原型和原型鏈
設(shè)計(jì)模式之構(gòu)造函數(shù)模式
揭秘命名函數(shù)表達(dá)式
深入理解J avaScript 系列(結(jié)局篇)
執(zhí)行上下文(Execution Contexts)
函數(shù)(Functions)
《你真懂 JavaScript 嗎?》答案詳解
設(shè)計(jì)模式之適配器模式
設(shè)計(jì)模式之組合模式
設(shè)計(jì)模式之命令模式
S.O.L.I.D 五大原則之單一職責(zé) SRP
編寫高質(zhì)量 JavaScript 代碼的基本要點(diǎn)
求值策略
閉包(Closures)
對(duì)象創(chuàng)建模式(上篇)
This? Yes,this!
設(shè)計(jì)模式之代理模式
變量對(duì)象(Variable Object)
S.O.L.I.D 五大原則之里氏替換原則 LSP
面向?qū)ο缶幊讨话憷碚?/span>
設(shè)計(jì)模式之單例模式
Function 模式(上篇)
S.O.L.I.D 五大原則之依賴倒置原則 DIP
設(shè)計(jì)模式之迭代器模式
立即調(diào)用的函數(shù)表達(dá)式
設(shè)計(jì)模式之享元模式
設(shè)計(jì)模式之原型模式
根本沒有“JSON 對(duì)象”這回事!
JavaScript 與 DOM(下)
面向?qū)ο缶幊讨?ECMAScript 實(shí)現(xiàn)
全面解析 Module 模式
對(duì)象創(chuàng)建模式(下篇)
設(shè)計(jì)模式之職責(zé)鏈模式
S.O.L.I.D 五大原則之開閉原則 OCP
設(shè)計(jì)模式之橋接模式
設(shè)計(jì)模式之策略模式
設(shè)計(jì)模式之觀察者模式
代碼復(fù)用模式(推薦篇)
作用域鏈(Scope Chain)
Function 模式(下篇)
設(shè)計(jì)模式之工廠模式

設(shè)計(jì)模式之命令模式

介紹

命令模式(Command)的定義是:用于將一個(gè)請(qǐng)求封裝成一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或者記錄請(qǐng)求日志,以及執(zhí)行可撤銷的操作。也就是說改模式旨在將函數(shù)的調(diào)用、請(qǐng)求和操作封裝成一個(gè)單一的對(duì)象,然后對(duì)這個(gè)對(duì)象進(jìn)行一系列的處理。此外,可以通過調(diào)用實(shí)現(xiàn)具體函數(shù)的對(duì)象來解耦命令對(duì)象與接收對(duì)象。

正文

我們來通過車輛購買程序來展示這個(gè)模式,首先定義車輛購買的具體操作類:

$(function () {
    var CarManager = {
        // 請(qǐng)求信息
        requestInfo: function (model, id) {
            return 'The information for ' + model +
        ' with ID ' + id + ' is foobar';
        },
        // 購買汽車
        buyVehicle: function (model, id) {
            return 'You have successfully purchased Item '
        + id + ', a ' + model;
        },
        // 組織view
        arrangeViewing: function (model, id) {
            return 'You have successfully booked a viewing of '
        + model + ' ( ' + id + ' ) ';
        }
    };
})();

來看一下上述代碼,通過調(diào)用函數(shù)來簡單執(zhí)行 manager 的命令,然而在一些情況下,我們并不想直接調(diào)用對(duì)象內(nèi)部的方法。這樣會(huì)增加對(duì)象與對(duì)象間的依賴?,F(xiàn)在我們來擴(kuò)展一下這個(gè) CarManager 使其能夠接受任何來自包括 model 和 car ID 的 CarManager 對(duì)象的處理請(qǐng)求。根據(jù)命令模式的定義,我們希望實(shí)現(xiàn)如下這種功能的調(diào)用:

CarManager.execute({ commandType: "buyVehicle", operand1: 'Ford Escort', operand2: '453543' });

根據(jù)這樣的需求,我們可以這樣啦實(shí)現(xiàn) CarManager.execute 方法:

CarManager.execute = function (command) {
    return CarManager[command.request](command.model, command.carID);
};

改造以后,調(diào)用就簡單多了,如下調(diào)用都可以實(shí)現(xiàn)(當(dāng)然有些異常細(xì)節(jié)還是需要再完善一下的):

CarManager.execute({ request: "arrangeViewing", model: 'Ferrari', carID: '145523' });
CarManager.execute({ request: "requestInfo", model: 'Ford Mondeo', carID: '543434' });
CarManager.execute({ request: "requestInfo", model: 'Ford Escort', carID: '543434' });
CarManager.execute({ request: "buyVehicle", model: 'Ford Escort', carID: '543434' });

總結(jié)

命令模式比較容易設(shè)計(jì)一個(gè)命令隊(duì)列,在需求的情況下比較容易將命令計(jì)入日志,并且允許接受請(qǐng)求的一方?jīng)Q定是否需要調(diào)用,而且可以實(shí)現(xiàn)對(duì)請(qǐng)求的撤銷和重設(shè),而且由于新增的具體類不影響其他的類,所以很容易實(shí)現(xiàn)。

但敏捷開發(fā)原則告訴我們,不要為代碼添加基于猜測的、實(shí)際不需要的功能,如果不清楚一個(gè)系統(tǒng)是否需要命令模式,一般就不要著急去實(shí)現(xiàn)它,事實(shí)上,在需求的時(shí)通過重構(gòu)實(shí)現(xiàn)這個(gè)模式并不困難,只有在真正需求如撤銷、恢復(fù)操作等功能時(shí),把原來的代碼重構(gòu)為命令模式才有意義。