设计模式之策略模式
标签(空格分隔): javascript设计模式
策略模式定义
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互转换 1 。
一个基于策略模式的程序至少由两个部分组成。第一个部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。第二部分是环境类Context,Context接受客户的请求,随后把请求委托给某一个策略类,Context中要维持对某个策略对象的引用。
策略模式实现例子
- 策略模式实现计算奖金
var strategies = {
"S": function(salary){
return salary * 4;
},
"A": function(salary){
return salary * 3;
},
"B": function(salary){
return salary * 2;
}
}
var calculateBouns = function(level,salary){
return strategies[level](salary);
};
console.log(calculateBouns("S",20000)); //80000
console.log(calculateBouns("A",10000)); //30000
console.log(calculateBouns("B",5000)); //10000
2.策略模式实现表单验证
/*******************校验策略**************************/
var strategies = {
isNonEmpty: function(value, errorMsg){
if(value === ""){
return errorMsg;
}
},
minLength: 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;
}
}
}
var validataFunc = function(){
var validator = new Validator();
/****************************添加一些校验规则**************************/
validator.add(registerForm.username,'isNonEmpty','用户名不能为空');
validator.add(registerForm.password,'minLength:6','密码长度不能少于6位');
validator.add(registerForm.phoneNumber,'isMobile','手机号码格式不正确');
var errorMsg = validator.start();
return errorMsg;
};
var Validator = function(){
this.cache = [];
};
Validator.prototype.add = function(dom,rule,errorMsg){
var self = this;
for(var i=0,rule;rule = rules[i++];){
(function(rule){
var strategyAry = rule.strategy.split(":");
var errorMsg = rule.errorMsg;
self.cache.push(function(){
var strategy = strategyAry.shift();
strategyAry.unshift(dom.value);
strategyAry.push(errorMsg);
return strategies[strategy].apply(dom,strategyAry);
});
})(rule)
}
};
Validator.prototype.start = function(){
for(var i=0,validataFunc;validataFunc = this.cache[i++];){
var msg = validataFunc();
if(msg){
return msg;
}
}
}
策略模式优缺点
- 优点
- 策略模式利用组合,委托和多态等技术和思想,可以有效地避免多重条件选择语句。
- 策略模式提供了对开放-封闭原则的完美支持,将算法封装在独立的strategy中,使得它们易于切换,易于理解,易于扩展。
- 策略模式中的算法也可复用在系统的其他地方,从而避免许多重复的复制粘贴工作。
- 在策略模式中利用组合和委托来让Context拥有执行算法的能力,这也是继承的一种更轻便的替代方案。
- 缺点
没有很严重的缺点
- “并且可以使它们相互转化”,这句话在很大程度上是相对于静态类型语言而言的。因为静态类型语言中有类型检查机制,所以各个策略类需要实现同样的接口。当它们的真正类型被隐藏在接口后面时,它们才能被相互替换。而在javascript这种“类型模糊”的语言中没有这种困扰,任何对象都可以被替换使用。因此,JavaScript中的“可以相互替换使用”表现为他们具有相同的目标和意图。 ↩