策略模式:定義一系列的算法,把它們一個個封裝起來,而且使它們能夠相互替換
生活小栗子:諸葛錦囊html
諸葛給劉備的錦囊妙計,遇到任何困難都有應對計策。策略模式實現的也是相似的場景。前端
再來一慄:給喜歡的女生買冰淇淋,事先不瞭解其喜愛,只能集齊各類味道,總會命中。就是比較 「費錢」,這也是策略模式的缺點,需事先考慮全部應對場景。git
實現方式:一個基於策略模式的程序至少由兩部分組成,第一個部分是一組策略類 Strategies(可變),策略類封裝類具體的算法,並負責具體的計算過程。第二個部分是環境類 Context(不變), Context 接收客戶的請求,隨後把請求委託給某一個策略類。
假設咱們一個開發團隊,人員組成包括(開發組長,後端,前端,測試)。開發組長領取開發任務(不變),但具體的任務執行人員可根據類型劃分(可變)。github
好比開發任務有如下幾項:算法
開發組長會根據任務類型,分發到對應的開發人員頭上,組長不承擔具體開發任務。因此每個開發人員就承擔 Strategy 的做用(獨立的任務執行),而組長擁有並可支配全部開發人員的資源,充當 Context 的角色。團隊每個開發人員「組合」起來就是一個 Strategies 類(執行開發任務)。 這個 Strategies 是可變的,若是說後續開發任務須要安卓的、IOS的支持,只要添加安卓、IOS開發人員配置便可(可擴展)。segmentfault
// 策略類(開發人員) var Strategies = { "backend": function(task) { console.log('進行後端任務:', task); }, "frontend": function(task) { console.log('進行前端任務:', task); }, "testend": function(task) { console.log('進行測試任務:', task); } }; // 環境類(開發組長) var Context = function(type, task) { typeof Strategies[type] === 'function' && Strategies[type](task); } Context('backend', '優化服務器緩存'); Context('frontend', '優化首頁加載速度'); Context('testend', '完成系統併發測試');
上述代碼帶來的好處:後端
策略模式的另外一個好處就是,消除了大部分的 if...else
/ switch...case
條件分支語句,代碼閱讀性提升。設計模式
// 沒有使用策略模式的組長... var Context = function(type, task) { if (type === 'backend') { // 把後端給我叫來 } else if (type === 'frontend') { // 把前端給我叫來 } else if (type === 'testend') { // 把測試給我叫來 } }
JavaScript 中,函數做爲「一等公民「,也稱「一等對象」。JavaScript 中 」高階函數「 應用中,函數可被做爲變量或參數進行傳遞或調用。所以在 JavaScript 中,咱們可將算法封裝成獨立的函數,並將它做爲參數傳遞給另外一個函數調用。緩存
// 封裝獨立的函數 var backend = function(task) { console.log('進行後端任務:', task); }; var frontend = function(task) { console.log('進行前端任務:', task); }; var testend = function(task) { console.log('進行測試任務:', task); }; // 環境類(開發組長) var Context = function(func, task) { typeof func === 'function' && func(task); } Context(backend, '優化服務器緩存'); Context(frontend, '優化首頁加載速度'); Context(testend, '完成系統併發測試');
少了 Strategies 策略類的外層包裹,函數更加獨立,並不妨礙其調用。使用函數替代策略類方式,正是咱們平常開發中常常用到的 「隱形」 策略模式。服務器
優勢:
if...else/switch...case
;缺點:
JavaScript設計模式整理系列正在更新中,敬請關注專欄 "前端進擊的巨人",獲取實時更新。
參考文章
本文首發Github,期待Star!
https://github.com/ZengLingYong/blog
做者:以樂之名 本文原創,有不當的地方歡迎指出。轉載請指明出處。