标签:
策略模式的定义是:定义一系列的算法,把它们一个个封转起来,并且使它们可以相互替换。
JavaScript版本的策略模式:
奖金系统:
var strategies = { "S": function(salary){ return salary*4; }, "A": function(salary){ return salary*3; }, "B": function(salary){ return salary*2; } }; var calculateBonus = function(level,salary){ return strategies[level](salary); }; console.log(calculateBonus(‘S‘,20000));//输出:80000 console.log(calculateBonus(‘A‘,10000));//输出:30000
使用策略模式实现缓动动画:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小球运动策略模式</title>
<style>
#div{
position: absolute;
background: blue;
width:50px;
height: 50px;
}
</style>
</head>
<body>
<div id="div">我是小球</div>
</body>
</html>
<script>
var tween = {
linear: function(t,b,c,d){
return c*t/d+b;
},
easeIn: function(t,b,c,d){
return c*(t/=d)*t+b;
},
strongEaseIn: function(t,b,c,d){
return c*(t/=d)*t*t*t*t+b;
},
strongEaseOut: function(t,b,c,d){
return c*((t=t/d-1)*t*t*t*t+1)+b;
},
sineaseIn: function(t,b,c,d){
return c*(t/=d)*t*t+b;
},
sineaseOut: function(t,b,c,d){
return c*((t=t/d-1)*t*t+1)+b;
}
};
var Animate = function(dom){
this.dom = dom;//进行运动的dom节点
this.startTime = 0;//动画开始时间
this.startPos = 0;
this.endPos = 0;
this.propertyName = null;
this.easing = null;
this.duration = null;
};
Animate.prototype.start = function(propertyName,endPos,duration,easing){ //启动这个动画
this.startTime = +new Date;
this.startPos = this.dom.getBoundingClientRect()[propertyName];//dom初始节点位置
this.propertyName = propertyName;//dom节点需要被改变的CSS属性名
this.endPos = endPos;//dom节点目标位置
this.duration = duration;//动画持续事件
this.easing = tween[easing];//缓动算法
var self = this;
var timeId = setInterval(function(){
if(self.step()===false){
clearInterval(timeId);
}
},19)
};
Animate.prototype.step = function(){ //代表小球运动的每一帧要做的事情
var t = +new Date;
if(t>=this.startTime+this.duration){//修正小球位置
this.update(this.endPos);//更新小球的CSS属性值
return false;
}
var pos = this.easing(t-this.startTime,this.startPos,this.endPos-this.startPos,this.duration);
this.update(pos);//更新小球的CSS属性值
};
Animate.prototype.update = function(pos){
this.dom.style[this.propertyName] = pos+‘px‘;
};
var div = document.getElementById(‘div‘);
var animate = new Animate(div);
animate.start(‘left‘,500,1000,‘strongEaseOut‘);
//animate.start(‘top‘,1500,500,‘strongEaseIn‘);
</script>
策略模式指的是定义一系列的算法,并且把它们封装起来。
表单验证:
校验逻辑:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>策略模式表单验证</title>
</head>
<body>
<form action="" id="registerForm" method="post">
请输入用户名:<input type="text" name="userName">
请输入密码:<input type="text" name="password">
请输入手机号码:<input type="text" name="phoneNumber">
<button>提交</button>
</form>
</body>
</html>
<script>
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;
}
}
};
//Validator实现
var Validator = function(){
this.cache = [];
};
Validator.prototype.add = function(dom,rules){
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 errorMsg = validataFunc();
if(errorMsg){
return errorMsg;
}
}
};
//用户调用代码
var registerForm = document.getElementById(‘registerForm‘);
var validataFunc = function(){
var validator = new validator();//创建一个validator对象
validator.add(registerForm.userName,[{
strategy:‘isNonEmpty‘,
errorMsg:‘用户名不能为空‘
},{
strategy:‘minLength:6‘,
errorMsg:‘用户名长度不能小于6位‘
}]);
validator.add(registerForm.password,[{
strategy:‘minLength:6‘,
errorMsg:‘密码长度不能小于6位‘
}]);
validator.add(registerForm.phoneNumber,[{
strategy:‘isMobile‘,
errorMsg:‘手机号码格式不正确‘
}]);
var errorMsg = validator.start();
return errorMsg;
};
registerForm.onsubmit = function(){
var errorMsg = validataFunc();
if(errorMsg){
alert(errorMsg);
return false;
}
};
</script>
策略模式的一些优点:
策略模式利用组合、委托和多态等技术思想,可以有效地避免多重条件选择语句。
策略模式提供了对开放-封闭原则的完美支持,将算法封装在独立的startegy中,使得它们易于切换,易于理解,易于扩展。
策略模式中的算法也可以复用在系统的其他地方,从而避免许多重复的复制性粘贴工作。
在策略模式中利用组合和委托让Context拥有执行算法的能力,这也是继承的一种更轻便的替代方案。
在JavaScript语言的策略模式中,策略类往往被函数所代替,这时策略模式就是一种"隐形"的模式。
JavaScript设计模式与开发实践---读书笔记(5) 策略模式
标签:
原文地址:http://www.cnblogs.com/6489c/p/5936756.html