什麼是策略。
策略就是根據形勢的發展而制定的行動方針。
比如說春節快要到了,我們要回家,回家我們就要選擇交通工具。怎麼回家我們就需要制定方案。比如說我吧,我們家在河南一個農村,不管是汽車,火車,飛機都沒有直達的。我可以選擇從北京到鄭州乘火車,然後從北京到長葛做長途汽車,然後從長葛到家做短途汽車。當然也可以選擇其他方式,這就要根據自己的實際需要,時間不緊花費又低我一般就選擇這個方案。
開發中的策略模式使用
策略模式定義:定義一系列的演算法,然後把它們一個個的封裝起來,這些封裝起來的演算法可以相互替換。
舉一個年終獎金計算的例子,分為A,B,C,D四類,其中A類總經理,B類部門經理,C類專案負責人,D類開發人員。
一般情況,程式碼實現如下:
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中,我們都知道,函式也是物件,所以更簡單的方法就是將每一種策略定義成函式,而非上面的實現方式。
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等庫和前端框架中比較常見。