Skip to content

Latest commit

 

History

History
95 lines (91 loc) · 3.76 KB

File metadata and controls

95 lines (91 loc) · 3.76 KB

状态模式

状态模式的关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变。 状态模式定义了状态与行为之间的关系,并将它们封装在一个类里。通过增加新的状态类,很容易增加新的状态和转换。

  • 一种状态一个类
  • 把动作委托给类

故事背景

我们来想象这样一个场景:有一个电灯,电灯上面只有一个开关。当电灯开着的时候,此时按下开关,电灯会切换到关闭状态; 再按一次开关,电灯又将被打开。同一个开关按钮,在不同 的状态下,表现出来的行为是不一样的

代码实现(未使用状态模式)

var Light = function(){ 
    this.state = 'off'; // 给电灯设置初始状态 off
    this.button = null;// 电灯开关按钮
};
Light.prototype.init = function(){
    var button = document.createElement( 'button' ),
    self = this;
    button.innerHTML = '开关';
    this.button = document.body.appendChild( button ); 
    this.button.onclick = function(){
        self.buttonWasPressed(); 
    }
};
Light.prototype.buttonWasPressed = function(){ 
    if ( this.state === 'off' ){
        console.log( '开灯' );
        this.state = 'on';
    } else if ( this.state === 'on' ){
        console.log( '关灯' );
        this.state = 'off'; 
    }
};
var light = new Light(); 
light.init();

重构思路

  • 定义 3 个状态类
  • 改写 Light 类,使用状态对象记录当前的状态
  • 提供一个方法来切换 light 对象的状态
/******************** 定义 3 个状态类 ************************/
// OffLightState:
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;
};
/******************** 提供一个 方法来切换 light 对象的状态 ************************/
Light.prototype.init = function(){
    var button = document.createElement( 'button' ),
    self = this;
    this.button = document.body.appendChild( button ); 
    this.button.innerHTML = '开关';
    this.currState = this.offLightState;
    this.button.onclick = function(){ 
        self.currState.buttonWasPressed();
    } 
};
Light.prototype.setState = function( newState ){
    this.currState = newState; 
};
var light = new Light(); 
light.init();

执行结果跟之前的代码一致,但是使用状态模式的好处很明显,它可以使每 一种状态和它对应的行为之间的关系局部化,这些行为被分散和封装在各自对应的状态类之中, 便于阅读和管理代码。 另外,状态之间的切换都被分布在状态类内部,这使得我们无需编写过多的 if、else 条件 分支语言来控制状态之间的转换。