JavaScript 設計模式(二):策略模式

策略模式

策略模式:定義一系列的算法甩卓,把它們一個個封裝起來凌节,并且使它們可以相互替換

生活小栗子:諸葛錦囊

諸葛給劉備的錦囊妙計,遇到任何困難都有應對計策亚隅。策略模式實現(xiàn)的也是類似的場景硼莽。

再來一栗:給喜歡的女生買冰淇淋,事先不了解其喜好枢步,只能集齊各種味道沉删,總會命中。就是比較 “費錢”醉途,這也是策略模式的缺點矾瑰,需事先考慮所有應對場景。

模式特點

  1. 策略類:算法封裝成獨立的函數(shù)/對象
  2. 環(huán)境類:根據(jù)不同參數(shù)調用對應的策略函數(shù)/對象執(zhí)行

模式實現(xiàn)

實現(xiàn)方式:一個基于策略模式的程序至少由兩部分組成隘擎,第一個部分是一組策略類 Strategies(可變)殴穴,策略類封裝類具體的算法,并負責具體的計算過程货葬。第二個部分是環(huán)境類 Context(不變)采幌, Context 接收客戶的請求,隨后把請求委托給某一個策略類震桶。

假設我們一個開發(fā)團隊休傍,人員組成包括(開發(fā)組長,后端蹲姐,前端磨取,測試)人柿。開發(fā)組長領取開發(fā)任務(不變),但具體的任務執(zhí)行人員可根據(jù)類型劃分(可變)忙厌。

比如開發(fā)任務有以下幾項:

  1. 優(yōu)化服務器緩存(后端任務)
  2. 優(yōu)化首屏加載速度(前端任務)
  3. 完成系統(tǒng)并發(fā)測試(測試任務)

開發(fā)組長會根據(jù)任務類型凫岖,分發(fā)到對應的開發(fā)人員頭上,組長不承擔具體開發(fā)任務逢净。所以每一個開發(fā)人員就承擔 Strategy 的作用(獨立的任務執(zhí)行)哥放,而組長擁有并可支配所有開發(fā)人員的資源,充當 Context 的角色爹土。團隊每一個開發(fā)人員“組合”起來就是一個 Strategies 類(執(zhí)行開發(fā)任務)甥雕。 這個 Strategies 是可變的,如果說后續(xù)開發(fā)任務需要安卓的胀茵、IOS的支持犀农,只要添加安卓、IOS開發(fā)人員配置即可(可擴展)宰掉。

// 策略類(開發(fā)人員)
var Strategies = {
    "backend": function(task) {
        console.log('進行后端任務:', task);
    },
    "frontend": function(task) {
        console.log('進行前端任務:', task);
    },
    "testend": function(task) {
        console.log('進行測試任務:', task);
    }
};

//  環(huán)境類(開發(fā)組長)
var Context = function(type, task) {
    typeof Strategies[type] === 'function' && Strategies[type](task);
}

Context('backend', '優(yōu)化服務器緩存');
Context('frontend', '優(yōu)化首頁加載速度');
Context('testend', '完成系統(tǒng)并發(fā)測試');

上述代碼帶來的好處:

  1. 算法獨立封裝,任務分發(fā)赁濒;
    開發(fā)組長不承擔具體開發(fā)任務(只做頂層設計轨奄,不跟年輕人搶飯碗)
  2. 復用性更好,不局限于 Context 調用拒炎;
    開發(fā)人員不愁下家(去哪寫代碼都是寫代碼)

策略模式的另一個好處就是挪拟,消除了大部分的 if...else / switch...case 條件分支語句,代碼閱讀性提高击你。

// 沒有使用策略模式的組長...
var Context = function(type, task) {
    if (type === 'backend') {
        // 把后端給我叫來
    } else if (type === 'frontend') {
        // 把前端給我叫來
    } else if (type === 'testend') {
        // 把測試給我叫來
    }
}

JavaScript 中玉组,函數(shù)作為“一等公民“,也稱“一等對象”丁侄。JavaScript 中 ”高階函數(shù)“ 應用中惯雳,函數(shù)可被作為變量或參數(shù)進行傳遞或調用。因此在 JavaScript 中鸿摇,我們可將算法封裝成獨立的函數(shù)石景,并將它作為參數(shù)傳遞給另一個函數(shù)調用。

// 封裝獨立的函數(shù)
var backend = function(task) {
    console.log('進行后端任務:', task);
};
var frontend = function(task) {
    console.log('進行前端任務:', task);
};
var testend = function(task) {
    console.log('進行測試任務:', task);
};

//  環(huán)境類(開發(fā)組長)
var Context = function(func, task) {
    typeof func === 'function' && func(task);
}

Context(backend, '優(yōu)化服務器緩存');
Context(frontend, '優(yōu)化首頁加載速度');
Context(testend, '完成系統(tǒng)并發(fā)測試');

少了 Strategies 策略類的外層包裹拙吉,函數(shù)更加獨立潮孽,并不妨礙其調用。使用函數(shù)替代策略類方式筷黔,正是我們?nèi)粘i_發(fā)中經(jīng)常用到的 “隱形” 策略模式往史。

適用場景

  1. 多重條件語句判斷,執(zhí)行對應的算法場景
  2. 表單校驗(validator)

優(yōu)缺點

  • 優(yōu)點:
    1. 利用組合佛舱、委托椎例、多態(tài)的技術和思想挨决,避免多重條件選擇語句 if...else/switch...case
    2. 復用性更高粟矿,算法函數(shù)可在系統(tǒng)其它地方使用凰棉;
    3. 支持設計模式 “開發(fā)-封閉原則“ ,算法封裝在獨立的 Strategy 中陌粹,易于維護和擴展撒犀;
    4. 策略模式使用 “組合和委托” 來讓 Context 擁有執(zhí)行算法的能力,一種替換對象繼承的可行方案
  • 缺點:
    1. 增加了許多策略類或對象(開發(fā)人員職能劃分明確掏秩,人員成本有所增加)或舞;
    2. 必須了解各個 Strategy 的不同點,違反 “最少知識原則”(組長手底下有對應的開發(fā)人員蒙幻,才不用自己那么苦逼)

參考文章

本文首發(fā)Github映凳,期待Star!
https://github.com/ZengLingYong/blog

作者:以樂之名
本文原創(chuàng)邮破,有不當?shù)牡胤綒g迎指出诈豌。轉載請指明出處。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抒和,一起剝皮案震驚了整個濱河市矫渔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摧莽,老刑警劉巖庙洼,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異镊辕,居然都是意外死亡油够,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門征懈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來石咬,“玉大人,你說我怎么就攤上這事卖哎÷挡梗” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵棉饶,是天一觀的道長厦章。 經(jīng)常有香客問我,道長照藻,這世上最難降的妖魔是什么袜啃? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮幸缕,結果婚禮上群发,老公的妹妹穿的比我還像新娘晰韵。我一直安慰自己,他們只是感情好熟妓,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布雪猪。 她就那樣靜靜地躺著,像睡著了一般起愈。 火紅的嫁衣襯著肌膚如雪只恨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天抬虽,我揣著相機與錄音官觅,去河邊找鬼。 笑死阐污,一個胖子當著我的面吹牛休涤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笛辟,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼功氨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了手幢?” 一聲冷哼從身側響起疑故,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弯菊,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踱阿,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡管钳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了软舌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片才漆。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖佛点,靈堂內(nèi)的尸體忽然破棺而出醇滥,到底是詐尸還是另有隱情,我是刑警寧澤超营,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布鸳玩,位于F島的核電站,受9級特大地震影響演闭,放射性物質發(fā)生泄漏不跟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一米碰、第九天 我趴在偏房一處隱蔽的房頂上張望窝革。 院中可真熱鬧购城,春花似錦、人聲如沸虐译。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漆诽。三九已至侮攀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拴泌,已是汗流浹背魏身。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蚪腐,地道東北人箭昵。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像回季,于是被迫代替她去往敵國和親家制。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • javascript設計模式與開發(fā)實踐 設計模式 每個設計模式我們需要從三點問題入手: 定義 作用 用法與實現(xiàn) 單...
    穿牛仔褲的蚊子閱讀 4,063評論 0 13
  • 在程序設計中泡一,我們也常常遇到類似的情況颤殴,要實現(xiàn)某一個功能有多種方案可以選擇。比如一個壓縮文件的程序鼻忠,既可以選擇zi...
    yufawu閱讀 369評論 0 3
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,103評論 1 32
  • 工廠模式類似于現(xiàn)實生活中的工廠可以產(chǎn)生大量相似的商品涵但,去做同樣的事情,實現(xiàn)同樣的效果;這時候需要使用工廠模式帖蔓。簡單...
    舟漁行舟閱讀 7,769評論 2 17
  • 工廠模式 單體模式 模塊模式 代理模式 職責鏈模式 命令模式 模板方法模式 策略模式 發(fā)布-訂閱模式 中介者模式 ...
    HelloJames閱讀 1,008評論 0 6