策略就是根據形勢的發展而制定的行動方針。javascript
好比說春節快要到了,咱們要回家,回家咱們就要選擇交通工具。怎麼回家咱們就須要制定方案。好比說我吧,咱們家在河南一個農村,無論是汽車,火車,飛機都沒有直達的。我能夠選擇從北京到鄭州乘火車,而後從北京到長葛作長途汽車,而後從長葛到家作短途汽車。固然也能夠選擇其餘方式,這就要根據本身的實際須要,時間不緊花費又低我通常就選擇這個方案。前端
策略模式定義:定義一系列的算法,而後把它們一個個的封裝起來,這些封裝起來的算法能夠相互替換。java
舉一個年終獎金計算的例子,分爲A,B,C,D四類,其中A類總經理,B類部門經理,C類項目負責人,D類開發人員。git
通常狀況,代碼實現以下:github
var calBonus = function (level, salary) { if( level === 'A') { return salary*2; } if( level === 'B') { return salary*1.5; } if( level === 'C') { return salary*1.0; } if( level === 'D') { return salary*0.75; } }
這種代碼的實現方式很常見,可是效果不是那麼好,在這個函數體內一個條件就是一個算法策略,在實際開發中它們每每實現比較複雜,代碼量比較大,一個兩個沒什麼,若是再增長几個或者十幾個呢,或者咱們在增長100個呢?明顯這種實現方式的彈性不好,複用性也比較差。算法
若是,代碼體積較小,分支較少使用條件判斷何嘗不可,可是若是,條件分支較多且代碼體積較大比建議。設計模式
開發中咱們每每會用的一種組合函數重構的方式來實現,代碼修改以下:前端框架
function levelA (salary) { return salary*2; } function levelB (salary) { return salary*1.5; } function levelC (salary) { return salary*1.0; } function levelD (salary) { return salary*0.75; } var calBonus = function(leveType, salary) { if(levelType === 'A') { return leveA(salary); } if(levelType === 'B') { return leveB(salary); } if(levelType === 'C') { return leveC(salary); } if(levelType === 'D') { return leveD(salary); } }
這樣修改後的代碼確實使用起來,比剛開始好了許多,可是這樣的實現方式,仍是彈性不足,若是擴展的話回事calBonus函數的體積愈來愈大。這時咱們每每會考慮設計模式。框架
首先,咱們須要建立一個策略類組,而後在建立一個獎金類。具體代碼實現以下:函數
// A類 function LevelA() {} LevelA.prototype.cal = function(salary) { return salary*2; } // B類 function LevelB() {} LevelB.prototype.cal = function(salary) { return salary*1.5; } // C類 function LevelC() {} LevelC.prototype.cal = function(salary) { return salary*1; } // D類 function LevelD() {} LevelD.prototype.cal = function(salary) { return salary*0.75; } // 定義一個獎金類 function Bonus () { this.strategy = null; this.salary = null; } // 獎金strategy Bonus.prototype.setStrategy = function(strategy) { this.strategy = strategy; } // 設置salary Bonus.prototype.setSalary = function(salary) { this.salary = salary; } // 獲取獎金 Bonus.prototype.getBonus = function() { return this.strategy.cals(this.salary) } // A var bonus = new Bonus(); bonus.setSalary(10000); bonus(new LevelA()); bonus.getBonus() // B var bonus = new Bonus(); bonus.setSalary(8000); bonus(new LevelB()); bonus.getBonus()
在javascript中,咱們都知道,函數也是對象,因此更簡單的方法就是將每一種策略定義成函數,而非上面的實現方式。
function levelA (salary) { return salary*2; } function levelB (salary) { return salary*1.5; } function levelC (salary) { return salary*1.0; } function levelD (salary) { return salary*0.75; } var Bonus = { levelA : levelA, levelB : levelB, levelC : levelC, levelD : levelD, }; var calBonus = function(level, salary) { return Bonus[level](salary); } calBonus('levelA', 30000); // 60000 // 添加一個E類 var levelE = function (salary) { return salary*0.5; } Bonus.levelE = levelE; calBonus('levelE', 5000); // 2500
這種實現方式,研究源碼的同窗常常遇到,在jQuery,validator等庫和前端框架中比較常見。