资讯专栏INFORMATION COLUMN

js策略模式vs状态模式

aaron / 1123人阅读

摘要:一策略模式定义把一些小的算法封装起来使他们之间可以相互替换把代码的实现和使用分离开来利用策略模式实现小方块缓动代码代码动画已消耗时间原始位置目标位置持续时间小球运动的时间要改变的属性例如缓动算法记录开始位置并设置定时器是否有要执行的

一.策略模式

1.定义:把一些小的算法,封装起来,使他们之间可以相互替换(把代码的实现和使用分离开来)
2.利用策略模式实现小方块缓动

html代码:

js代码:

var container = document.getElementById("container");
container.style.height = window.innerHeight +"px";
var tween = {//t动画已消耗时间、b原始位置、c目标位置、d持续时间
  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;
    this.startTime = 0;
    this.startPos = 0;
    this.endPos = 0;
    this.duration = 0;//小球运动的时间
    this.propertyName = null;//要改变的css属性,例如top,left
    this.easing=null;//缓动算法
};
animate.prototype.start = function(endPos,duration,propertyName,easing){
    //记录开始位置,并设置定时器是否有要执行的步数
    this.startTime = new Date();
    this.startPos = this.dom.getBoundingClientRect()[propertyName];
    this.endPos = endPos;
    this.duration = duration;
    this.propertyName = propertyName;
    this.easing = tween[easing];
    var setTime = setInterval(function(){
        if(this.step()){
            clearsetInterval(setTime);
        }
        this.step();
    }.bind(this),20)

}
animate.prototype.step = function(){//动画执行一步需要的操作
    var t = +new Date();
    if(t>this.startTime+this.duration){
        this.update(this.endPos);
        return false;
    }
    var pos = 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";
        return false;
    }
    this.dom.style[this.propertyName] = pos +"px";
}
//调用
var move = document.getElementById("move");
var a = new animate(move);
 a.start(100,1000,"bottom","sineaseIn")

3.优缺点
优点:避免多重条件判断语句;遵循开放-封闭原则,具有较好的扩展性,便于切换;可复用性;
缺点:违背最少知识原则(向用户暴露所有的实现)

二.状态模式

1.定义:允许一个对象在其状态改变时改变他的行为,对象看起来视乎修改了他的类
2.状态模式例子:电源开关三种状态的互相变化(状态驱动行为)

var Light = function(){
   this.offState = new offLightState(this);
   this.weakState = new weakLightState(this);
   this.strongState = new strongLightState(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;
}
//状态模式的关键是把每种状态都封装成一个类
var offLightState = function(light){
    this.light = light;
};
offLightState.prototype.btnPressed = function(){
    console.log("调弱");
    this.light.setState(this.light.weakState);
}
var weakLightState = function(light){
    this.light = light;
};
weakLightState.prototype.btnPressed = function(){
    console.log("调强");
    this.light.setState(this.light.strongState);
}
var strongLightState = function(light){
    this.light = light;
};
strongLightState.prototype.btnPressed = function(){
    console.log("关闭");
    this.light.setState(this.light.offState);
}

var light = new Light();
light.start();//调弱 调强 关闭

3.状态模式是状态机的一种实现方式,还可以直接将状态委托给字面量,利用Function.prototype.call()调用,达到和状态模式一样的效果

var FMC = {
    on:{
        buttonWasPressed:function(){
            console.log("变弱")
            this.current = FMC.weak;
        }
    },
    weak:{
        buttonWasPressed:function(){
        console.log("变强")
        this.current = FMC.strong;
        }
    },
    strong:{
        buttonWasPressed:function(){
        console.log("变更强")
        this.current = FMC.superstrong;
        }
    },
    superstrong:{
        buttonWasPressed:function(){
            console.log("关闭")
            this.current = FMC.off;
        }
    },
    off:{
        buttonWasPressed:function(){
            console.log("打开")
            this.current = FMC.on;
        }
    }
}
var light = 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);
}
var l = new light();
l.start();

4.优缺点
优点:可扩展性较好,可以方便的增加新的状态;相比冗余的if else判断,状态模式将逻辑封装在类中,避免Context无限膨胀
缺点:代码逻辑分散在各个类中,造成逻辑分散的问题

三.对比两种模式

相同点:这两种模式都只有一个上下文、一些策略类或者是状态类,上下文把请求委托给这些类来执行
不同点:这两种模式的目的是不同的;策略模式的策略类之间是相互平行平等的,而状态模式的状态类把状态和行为封装到一起,把逻辑实现封装到类中,状态之间的切换也早被规定完成.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107805.html

相关文章

  • js策略模式vs状态模式

    摘要:一策略模式定义把一些小的算法封装起来使他们之间可以相互替换把代码的实现和使用分离开来利用策略模式实现小方块缓动代码代码动画已消耗时间原始位置目标位置持续时间小球运动的时间要改变的属性例如缓动算法记录开始位置并设置定时器是否有要执行的 一.策略模式 1.定义:把一些小的算法,封装起来,使他们之间可以相互替换(把代码的实现和使用分离开来)2.利用策略模式实现小方块缓动 html代码: ...

    mingde 评论0 收藏0
  • 忘了再看设计模式-行为型

    摘要:推文用设计模式解构三国是一种什么体验行为型设计模式一策略模式工厂模式优化结构状态模式随着状态改变而改变行为。推文状态机与状态模式责任链模式多个对象依次处理请求前者指定后者。代理模式代理针对一个对象,为了增加控制等中介双方都是多个,为了解耦。 策略模式 选择使用封装好的一系列算法,可相互替换。 类比:商店[Context]买完衣服买单[Stratege](现金[Concrete Stra...

    ShevaKuilin 评论0 收藏0
  • 第6章:可维护性软件构建方法 6.2可维护性设计模式

    摘要:抽象工厂模式将具有共同主题的对象工厂分组。对可重用性和可维护性设计模式的高层考虑创造性模式工厂方法模式也称为虚拟构造器意图定义一个用于创建对象的接口,但让子类决定实例化哪个类。 大纲 创造性模式 工厂方法模式创建对象而不指定要创建的确切类。 抽象工厂模式将具有共同主题的对象工厂分组。 Builder模式通过分离构造和表示来构造复杂的对象。 结构模式 Bridge将抽象从其实现中分...

    VioletJack 评论0 收藏0
  • 我的Java设计模式-策略模式

    摘要:孙膑心里一万个草泥马在奔腾,差点没噎死自己滚一边去,我们这盘跟他赛马开始,策略模式上场。在设计模式之禅中的提出通过策略枚举和反射机制对策略模式进行改良,膜拜了但是要添加或淘汰策略,还是得去对枚举进行修改,也不符合开闭原则。 今天给大家说说田忌赛马的故事。如有雷同,纯属巧合!话说在战国时期,群雄割据,硝烟四起,茶余饭后还是少不了娱乐活动的,其中赛马是最火爆的。一天,孙膑看到田忌像个死鸡似...

    zilu 评论0 收藏0

发表评论

0条评论

aaron

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<