設計模式總結算法
策略模式 (Strategy Pattern)又稱政策模式,其定義一系列的算法,把它們一個個封裝起來,而且使它們能夠互相替換。封裝的策略算法通常是獨立的,策略模式根據輸入來調整採用哪一個算法。關鍵是策略的實現和使用分離。設計模式
假設咱們如今須要根據訪問網站的不一樣用戶(用戶級別分爲NORMAL,VIP,SVIP
)來判斷將反饋不一樣的廣告。上代碼!閉包
function ReturnAdvertisment(userType="NORMAL"){
if(userType==="NORMAL"){
return "中華魔力炫白";
}else if(userType==="VIP"){
return "肯德基";
}else if(userType==="SVIP"){
return "蘭博基尼";
}
}
複製代碼
這個時候咱們調用:app
ReturnAdvertisment("NORMAL");//中華魔力炫白
ReturnAdvertisment("VIP");//肯德基
ReturnAdvertisment("SVIP");//蘭博基尼
複製代碼
經過輸入用戶類型加上if else
便可以返回不一樣的廣告信息!可是萬一老闆說用戶的類型要加好幾種~!那咋整呢?是否是須要修改函數的代碼?這是違反咱們的開放-封閉
原則的!函數
將計算返回的代碼抽離出來看成一個對象,用戶類型看成key值。優化
const userMap={
NORMAL:function(){
return "中華魔力炫白"
},
VIP:function(){
return "肯德基"
},
SVIP:function(){
return "蘭博基尼"
}
}
/*計算返回廣告類型*/
function ReturnAdvertisment(userType="NORMAL"){
return userMap[userType]();
}
複製代碼
這樣算法的實現和算法的使用分離了,增長新的用戶也十分簡單了!網站
userMap.SSVIP=function(){
return "湯臣一品豪宅";
}
複製代碼
若是你但願計算算法隱藏起來,那麼能夠藉助IIFE
使用閉包的方式,這時須要添加增長策略的入口,以方便擴展。spa
const ReturnAdvertismentWrapper = (function() {
/* 售價計算方式 */
const userMap={
NORMAL:function(){
return "中華魔力炫白"
},
VIP:function(){
return "肯德基"
},
SVIP:function(){
return "蘭博基尼"
}
}
return {
returnAdvertisment(userType="NORMAL"){
return userMap[userType]();
},
addReturnAdvertisment: function(userType, fn) {
// 註冊新用戶
if (userMap[userType]) return
userMap[userType] = fn
}
}
})()
ReturnAdvertismentWrapper.returnAdvertisment("NORMAL");//中華魔力炫白
ReturnAdvertismentWrapper.addReturnAdvertisment("SSVIP",function(){return "湯臣一品豪宅"})
複製代碼
這樣算法就被隱藏起來,而且預留了增長策略的入口,便於擴展。設計
以上例子中,計算返回廣告的過程能夠當作策略(Strategy),這些策略能夠相互更換,而具體的計算過程能夠被稱爲上下文(Context),全部的策略能夠被稱做策略合集(StrategyMap)。3d
使用通用的方法實現一下:const StrategyMap={};
function context(type,...rest){
return StrategyMap[type] && StrategyMap[type](...rest);
}
StrategyMap.NORMAL=function(){
return "中華魔力炫白";
}
context("NORMAL");//中華魔力炫白
複製代碼