js策略模式vs状态模式
时间:2023-04-03 00:12:44
HTML
一、策略模式1、定义:封装一些小算法,使其可以相互替换(单独代码实现和使用)2、使用策略模式实现小方块缓动html代码:
js代码:varcontainer=document.getElementById('container');container.style.height=window.innerHeight+"px";vartween={//t动画已经消耗时间,b原位置,c目标位置,d持续时间linear:function(t,b,c,d){returnc*t/d+b;},easeIn:function(t,b,c,d){返回c*(t/=d)*t+b;},strongEaseIn:function(t,b,c,d){返回c*(t/=d)*t*t*t*t+b;},strongEaseOut:function(t,b,c,d){返回c*((t=t/d-1)*t*t*t*t+1)+b;},sineaseIn:function(t,b,c,d){返回c*(t/=d)*t*t+b;},sineaseOut:function(t,b,c,d){返回c*((t=t/d-1)*t*t+1)+b;}};varanimate=function(dom){this.dom=dom;this.startTime=0;this.startPos=0;this.endPos=0;this.duration=0;//小球运动的时间this.propertyName=null;//要改变的css属性,比如top,leftthis.easing=null;//缓动算法};animate.prototype.start=function(endPos,duration,propertyName,easing){//记录开始位置,并设置定时器是否有要执行的步数this.startTime=newDate();this.startPos=this.dom.getBoundingClientRect()[propertyName];this.endPos=endPos;this.duration=持续时间;这。属性名=属性名;这。缓动=tween[缓动];varsetTime=setInterval(function(){if(this.step()){clearsetInterval(setTime);}this.step();}.bind(this),20)}animate.prototype.step=function(){//动画需要执行一步vart=+newDate();if(t>this.startTime+this.duration){this.update(this.endPos);返回假;}varpos=this.easing(t-this.startTime,this.startPos,this.endPos,this.duration);//t动画运行时间,b原位置,c目标位置,d持续时间this.update(pos);}animate.prototype.update=function(pos){//更新div的css属性if(pos>window.innerWidth||pos>window.innerHeight){this.dom.style[this.propertyName]=this.endPos+'px';返回假;}this.dom.style[this.propertyName]=pos+'px';}//调用varmove=document.getElementById('move');vara=newanimate(move);a.start(100,1000,'bottom','sineaseIn')3.优缺点优点:避免多重条件判断语句;遵循开闭原则,具有更好的扩展性,易于切换;可重用性;缺点:违反最少知识原则(将所有实现暴露给用户)2.状态模式1.定义:允许一个对象在状态改变时改变它的行为,对象好像修改了他的类2.状态模式例子:电源开关三种状态的相互变化(状态驱动行为)varLight=function(){this.offState=newoffLightState(this);this.weakState=newweakLightState(this);this.strongState=newstrongLightState(this);this.button=null;}Light.prototype.start=function(){this.button=document.getElementById('change');this.current=this.offState;this.button.onclick=function(){this.current.btnPressed();}.bind(this);}Light.prototype.setState=function(newState){//改变状态this.current=newState;}//状态模式的关键是将每个状态封装到一个类中varoffLightState=function(light){this.light=light;};offLightState.prototype.btnPressed=function(){console.log('weak');this.light.setState(this.light.weakState);}varweakLightState=function(light){this.light=light;};weakLightState.prototype.btnPressed=function(){console.log('强度');this.light.setState(this.light.strongState);}varstrongLightState=function(light){this.light=light;};strongLightState.prototype.btnPressed=function(){console.log('off');this.light.setState(this.light.offState);}varlight=newLight();light.start();//调优3.状态模式是状态机的一种实现。也可以直接将状态委托给字面量,使用Function.prototype.call()实现和状态模式一样的效果。varFMC={on:{buttonWasPressed:function(){console.log('Weakened')this.current=FMC.weak;}},weak:{buttonWasPressed:function(){console.log('Weakened')this.current=FMC.strong;}},strong:{buttonWasPressed:function(){console.log('变强')this.current=FMC.superst荣;}},超强:{buttonWasPressed:function(){console.log('off')this.current=FMC.off;}},off:{buttonWasPressed:function(){console.log('open')this.current=FMC.on;}}}varlight=function(){this.current=FMC.off;this.button=null;}light.prototype.start=function(){this.button=document.getElementById('change');console.log("current",this.current)this.button.onclick=function(){this.current.buttonWasPressed.call(this);}.bind(this);}varl=newlight();l.开始();4.优缺点优点:可扩展性更好,可以方便的增加新的状态;相比冗余的ifelse判断,state模式将逻辑封装在类中,避免了Context无限膨胀的弊端:代码逻辑分散在各个类中,造成逻辑分散的问题。3.比较两种模式的相同点:两种模式都只有一个context,一些policy类或者state类,context将请求委托给这些Class来实现区别:这两种模式的目的不同;策略模式的策略类是并行且相等的,而状态模式的状态类将状态和行为封装在一起,并将逻辑实现封装到类中,状态之间的切换也是规定完成的。