Skip to content

策略模式 #17

Description

@isNeilLin

策略模式

定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。

并且使它们可以相互替换”,这句话在很大程度上是相对于静态类型语言而言的。因为静态类型语言中有类型检查机制,所以各个策略类需要实现同样的接口。当它们的真正类型被隐藏在接口后面时,它们才能被相互替换。而在JavaScript这种“类型模糊”的语言中没有这种困扰,任何对象都可以被替换使用。因此,JavaScript中的“可以相互替换使用”表现为它们具有相同的目标和意图。

策略模式的目的就是将算法的使用与算法的实现分离开来。

一个基于策略模式的程序至少由两部分组成。第一个部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。 第二个部分是环境类Context,Context接受客户的请求,随后把请求委托给某一个策略类。要做到这点,说明Context中要维持对某个策略对象的引用

// JavaScript版本的策略模式varstrategies={'S': function(salary){returnsalary*4;},'A': function(salary){returnsalary*3;},'B': function(salary){returnsalary*2;}}varcalculate=function(level,salary){returnstrategies[level](salary);}

缓动动画

/*@param { t: 动画已消耗的时间, b: 小球原始位置, c: 小球目标位置, d: 动画持续的总时间	}*/vartween={linear: function(t,b,c,d){returnc*t/d+b;},easeIn: function(t,b,c,d){returnc*(t/=d # 策略模式定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。>并且使它们可以相互替换”,这句话在很大程度上是相对于静态类型语言而言的。因为静态类型语言中有类型检查机制,所以各个策略类需要实现同样的接口。当它们的真正类型被隐藏在接口后面时,它们才能被相互替换。而在JavaScript这种“类型模糊”的语言中没有这种困扰,任何对象都可以被替换使用。因此,JavaScript中的“可以相互替换使用”表现为它们具有相同的目标和意图。策略模式的目的就是将算法的使用与算法的实现分离开来。一个基于策略模式的程序至少由两部分组成。第一个部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。第二个部分是环境类Context,Context接受客户的请求,随后把请求委托给某一个策略类。要做到这点,说明Context中要维持对某个策略对象的引用```javascript// JavaScript版本的策略模式varstrategies={
'S': function(salary){returnsalary*4;},'A': function(salary){returnsalary*3;},'B': function(salary){returnsalary*2;}}varcalculate=function(level,salary){returnstrategies[level](salary);}

缓动动画

/*
@param{t: 动画已消耗的时间,b: 小球原始位置,c: 小球目标位置,d: 动画持续的总时间})*t+b;},
strongEaseIn: function(t,b,c,d){returnc*(t/=d)*t*t*t*t+b;},strongEaseOut: function(t,b,c,d){returnc*((t=t/d-1)*t*t*t*t+1)+b;},sineaseIn: function(t,b,c,d){returnc*(t/=d)*t*t+b;},sineaseOut: function(t,b,c,d){returnc*((t=t/d-1)*t*t+1)+b;}}varAnimate=function(dom){this.dom=dom;this.startTime=0;this.startPos=0;this.endPos=0;this.easing=null;this.duration=null;this.prototyName=null;}Animate.prototype.start=function(prototyName,endPos,duration,easing){this.startTime=+newDate;this.startPos=this.dom.getBoundingClientRect()[prototyName];this.prototyName=prototyName;this.endPos=endPos;this.duration=duration;this.easing=tween[easing];// 缓动算法varself=this;vartimeId=setInterval(function(){if(self.step()===false){clearInterval(timeId);}})}Animate.prototype.step=function(){vart=+newDate;if(t>=this.startTime+this.duration){this.update(this.endPos);returnfalse;}varpos=this.easing(t-this.startTime,this.startPos,this.endPos-this.startPos,this.duration)this.update(pos);}Animate.prototype.update=function(pos){this.dom.style[this.prototyName]=pos+'px';}vardiv=document.getElementById('div');varanimate=newAnimate(div);animate.start('left',500,1000,'strongEaseOut');

表单验证

<body><formid="registerForm">
请输入用户名:<inputtype="text"name="userName"/><br>
请输入密码:<inputtype="text"name="password"/><br>
请输入手机号码:<inputtype="text"name="phoneNumber"/><br><button>提交</button></form><scripttype="text/javascript">
// 表单校验
var strategies = {isEmpty: function(val,errormsg){if(val===''){returnerrormsg;}},minLength: function(val,length,errormsg){if(val.length<length){returnerrormsg;}},isMobile: function(val,errormsg){if(!/(^1[3|5|8][0-9]{9}$)/.test(val)){returnerrormsg;}}}
var Validator = function(){this.cache=[];}
Validator.prototype.add = function(dom, rule, msg){varary;if(arguments.length===3){ary=rule.split(':');varstrategy=strategies[ary.shift()];ary.unshift(dom.value);ary.push(msg);this.cache.push(function(){returnstrategy.apply(this,ary);})}else if(arguments.length===2&&(Object.prototype.toString.call(rule)==='[objectArray]')){rule.map(ruleObj=>{this.add(dom,ruleObj.strategy,ruleObj.errormsg);})}}Validator.prototype.start=function(){for(vari=0,func;func=this.cache[i++];){varmsg=func();if(msg){
return msg;}}}varValidatorFuc=function(){varvalidator=newValidator();validator.add(registerForm.userName,[{strategy: 'isEmpty',errormsg: '用户名不能为空'},{strategy: 'minLength:8',errormsg: '用户名长度不能少于8位'}]);validator.add(registerForm.password,'minLength:6','密码长度不能少于6位');validator.add(registerForm.userName,'isMobile','手机号格式不正确');varerrormsg=validator.start();returnerrormsg;}
document.getElementById('registerForm').onsubmit = function(e){e.preventDefault();varerrorMsg=ValidatorFuc();// 如果errorMsg有确切的返回值,说明未通过校验if(errorMsg){alert(errorMsg);returnfalse;// 阻止表单提交}}</script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions