【javascript】javasrcipt设计模式之状态模式

使用场景

解决多个【ifelse】嵌套,将其封装成若干个方法

区分事物内部的状态,事物内部的状态的改变往往会带来事物的行为的改变

简单的多个状态直接切换的时候

//两个状态之间的切换,使用if-else来切换,在有多个状态的时候,这样的切换就会嵌套很多的条件判断语句,如果加入新的状态,修改代码也比较困难
Light.prototype.buttonWasPressed = function(){
        if ( this.state === 'off' ){
            console.log( '开灯' );
            this.state = 'on';
        }else if ( this.state === 'on' ){
            console.log( '关灯' );
            this.state = 'off';
        }
    };

状态模式的关健就是: 把事物的每种状态都封装成单独的类,跟此状态相关的行为都被封装在这个类的内部。只要有交互行为,只需要在上下文中,把这个请求委托给当前的对象状态即可,该状态对象会负责渲染它自身的行为

封装状态

var OffLightState = function( light ){
           this.light = light;
           };
        
   OffLightState.prototype.buttonWasPressed = function(){
       console.log( '弱光' ); // offLightState 对应的行为
         this.light.setState( this.light.weakLightState ); // 切换状态到weakLightState
    };
   // WeakLightState:
   var WeakLightState = function( light ){
     this.light = light;
   };

   WeakLightState.prototype.buttonWasPressed = function(){
       console.log( '强光' ); // weakLightState 对应的行为
       this.light.setState( this.light.strongLightState ); // 切换状态到strongLightState
      };
   // StrongLightState:
     var StrongLightState = function( light ){
       this.light = light;
   };

    StrongLightState.prototype.buttonWasPressed = function(){
       console.log( '关灯' ); // strongLightState 对应的行为
       this.light.setState( this.light.offLightState ); // 切换状态到offLightState
   };
      

在Light类中为每个状态类都创建一个状态对象,这样一来就可以很明显的看到电灯一共有多少个状态

var Light = function(){
    this.offLightState = new OffLightState( this );
    this.weakLightState = new WeakLightState( this );
    this.strongLightState = new StrongLightState( this );
    this.button = null;
};

在button按钮被按下的时候,通过self.currState.buttonWasPressed()将请求委托为当前的状态去执行。

Light.prototype.init = function(){
    var button = document.createElement( 'button' ),
    self = this;
    button.innerHTML = '已关灯';
    this.button = document.body.appendChild( button );
    this.button.onclick = function(){
        //初始化下就是调用FSM.off的方法设置内部状态self.currState.buttonWasPressed.call( self ); // 把请求委托给FSM 状态机
    }
};
var FSM = {
    off: {
        buttonWasPressed: function(){
            console.log( '关灯' );
            this.button.innerHTML = '下一次按我是开灯';
            this.currState = FSM.on;
        }
    },
    on: {
        buttonWasPressed: function(){
            console.log( '开灯' );
            this.button.innerHTML = '下一次按我是关灯';
            this.currState = FSM.off;
        }
    }
};
var light = new Light();
light.init();

posted @ 2018-04-11 09:24  teemor  阅读(207)  评论(0编辑  收藏  举报