javaScript设计模式与开发实践-策略模式
声明:这个系列是阅读《JavaScript设计模式与开发实践》 —-曾探@著一书的读书笔记
1、策略模式
定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换
目的:就是将算法的使用与算法的实现分离出来。
一个基于策略模式的程序至少由两部分组成。第一部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。第二部分是环境 类context,context接受客户的请求,随后把请求委托给某一个策略类。
列子:
1、员工的工资数额和他的绩效考核等级
<script>
var perS=function(){};
perS.prototype.calulate=function(salary){
return salary *4;
}
var perA=function(){};
perA.prototype.calulate=function(salary){
return salary *3;
}
var perB=function(){};
perB.prototype.calulate=function(salary){
return salary *2;
}
var perC=function(){};
perC.prototype.calulate=function(salary){
return salary;
}
//定义奖金
var Bonus=function(){
this.salary=null;//原始工资
this.strategy=null;//绩效等级对应的策略对象
};
Bonus.prototype.setSalary=function(salary){
this.salary=salary;//设置员工原始工资
}
Bonus.prototype.setStrategy=function(strategy){
this.strategy=strategy;//设置员工绩效等级对应的策略对象
}
Bonus.prototype.getBonus=function(strategy){//取得奖金额
return this.strategy.calulate(this.salary) //把计算奖金的操作委托给对应的策略对象
}
var bonus=new Bonus();
bonus.setSalary(1000);
bonus.setStrategy(new perS());//设置策略对象
console.log(bonus.getBonus())//输出:4000;
</script>
2、直接对应函数
<script>
var strategies={
"S":function(salary){
return salary*4;
},
"A":function(salary){
return salary*3;
},
"B":function(salary){
return salary*2;
}
}
var calulateBonus=function(level,salary){
return strategies[level](salary);
}
console.log(calulateBonus('S',2000));//输出:8000;
console.log(calulateBonus('A',2000));//输出:6000;
</script>
3、实现缓动画
<body>
<div style="position:absolute;background:blue" id="div">我是div</div>
</body>
<script type="text/javascript">
var Animate = function( dom ){
this.dom = dom; // 进行运动的dom 节点
this.startTime = 0; // 动画开始时间
this.startPos = 0; // 动画开始时,dom 节点的位置,即dom 的初始位置
this.endPos = 0; // 动画结束时,dom 节点的位置,即dom 的目标位置
this.propertyName = null; // dom 节点需要被改变的css 属性名
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 ){ // (1)
this.update( this.endPos ); // 更新小球的CSS 属性值
return false;
}
var pos = this.easing( t - this.startTime, this.startPos, this.endPos - this.startPos, this.duration );
// pos 为小球当前位置
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>