1.策略模式的定義
- 策略模式是用來(lái)封裝算法的章姓,可以用來(lái)封裝一組相同類(lèi)型的業(yè)務(wù)規(guī)則饶套,只要這些業(yè)務(wù)規(guī)則指向的目標(biāo)一致,并且可以被替換使用声滥,就可以用策略模式來(lái)封裝他們。
- 在js中可以用一個(gè)map對(duì)象來(lái)實(shí)現(xiàn)一個(gè)策略類(lèi)侦香,其中包含有各種業(yè)務(wù)邏輯函數(shù)落塑,然后用另一個(gè)Context類(lèi)來(lái)根據(jù)實(shí)際情況的不同,來(lái)使用不同的策略來(lái)處理業(yè)務(wù)罐韩。
- 策略模式的常見(jiàn)應(yīng)用就是憾赁,可以用來(lái)實(shí)現(xiàn)一個(gè)表單驗(yàn)證器,來(lái)驗(yàn)證用戶(hù)是否輸入的合法數(shù)據(jù)散吵。
2.表單驗(yàn)證器
表單驗(yàn)證器的核心思想就是首先封裝一個(gè)策略對(duì)象出來(lái)龙考,然后在驗(yàn)證器類(lèi)中使用一個(gè)數(shù)組來(lái)存放各種驗(yàn)證邏輯,驗(yàn)證邏輯則可以用一系列回調(diào)函數(shù)來(lái)表示矾睦,等到需要驗(yàn)證時(shí)晦款,即調(diào)用存放的各個(gè)驗(yàn)證邏輯。
(function(){
//策略對(duì)象枚冗,主要為各種校驗(yàn)規(guī)則
var strategies={
required: function(value,errorMsg){
if(value===''){
return errorMsg;
}
},
minLength: function(value,length,errorMsg){
if(value.length<length){
return errorMsg;
}
},
maxLength: function(value,length,errorMsg){
if(value.length>length){
return errorMsg;
}
},
isMobile: function(value,errorMsg){
if(!/^1[3|5|8][0-9]{9}$/.test(value)){
return errorMsg;
}
}
}
//Validater驗(yàn)證器類(lèi),context類(lèi)來(lái)使用相應(yīng)的策略對(duì)象中的方法
function Validater(){
this.validaters=[];
}
//為一個(gè)dom添加單一的驗(yàn)證規(guī)則
Validater.prototype.add=function(dom,rule,errorMsg){
this.validaters.push(function(){
var arg=rule.split(':');
var strategy=arg.shift();
arg.unshift(dom.value);
arg.push(errorMsg);
console.log(arg);
return strategies[strategy].apply(dom,arg);
});
};
//為一個(gè)dom添加多個(gè)驗(yàn)證規(guī)則
Validater.prototype.set=function(dom,rules){
var self=this;
rules.forEach(function(rule){
//再循環(huán)中傳遞回調(diào)函數(shù)時(shí)缓溅,需要注意將循環(huán)值用立即執(zhí)行函數(shù)拷貝一份,
//保存起來(lái)赁温,方便閉包進(jìn)行引用
(function(rule){
self.validaters.push(function(){
var arg=rule.strategy.split(':');
var strategy=arg.shift();
arg.unshift(dom.value);
arg.push(rule.errorMsg);
return strategies[strategy].apply(dom,arg);
});
})(rule);
});
};
//開(kāi)始進(jìn)行驗(yàn)證坛怪,找到第一個(gè)驗(yàn)證問(wèn)題即返回
Validater.prototype.start=function(){
for(var i=0,len=this.validaters.length;i<len;i++){
var msg=this.validaters[i]();
if(msg){
return msg;
}
}
};
//將驗(yàn)證器類(lèi)暴露出來(lái),方便外界調(diào)用
window.Validater=Validater;
})();
這里需要注意的一點(diǎn)就是股囊,在循環(huán)中添加驗(yàn)證邏輯的回調(diào)函數(shù)時(shí)袜匿,因?yàn)槭褂昧碎]包,所以需要使用立即執(zhí)行函數(shù)稚疹,將循環(huán)的數(shù)據(jù)進(jìn)行一次拷貝居灯,避免在調(diào)用回調(diào)函數(shù)時(shí),引用的都是最后一個(gè)循環(huán)的數(shù)據(jù)。
3.策略模式的本質(zhì)
在函數(shù)作為一等對(duì)象的語(yǔ)言中穆壕,策略模式是隱形的待牵,策略strategy就是值為函數(shù)的變量±可以將不同的業(yè)務(wù)邏輯函數(shù)傳遞到主函數(shù)中,當(dāng)對(duì)這些業(yè)務(wù)邏輯函數(shù)進(jìn)行調(diào)用時(shí)偎行,不同的函數(shù)會(huì)返回不同的執(zhí)行結(jié)果川背,即使用了函數(shù)對(duì)象的多態(tài)性。