允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。(开关灯)
状态模式的通用结构:
在一个Light的构造函数中,我们要创建每一个状态类的实例对象,Context将持有这些状态对象引用,以便把请求委托给状态对象。
//关灯
var OffLightState = function( light ){ this.light = light; } OffLightState.prototype.buttonWasPress = function(){ console.log('弱光'); this.light.setCurrState = ( this.light.weakLightState ); }
//弱光 var WeakLightState = function( light ){ this.light = light; } WeakLightState.prototype.buttonWasPress = function(){ console.log('强光'); this.light.setCurrState = ( this.light.StrongLightState ); } var Light = function() { this.offLightState = new OffLightState( this ); this.weakLightState = new WeakLightState( this ); this.strongLightState = new StrongLightState( this ); this.button = null; }; 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.buttonWasPress(); } } Light.prototype.setCurrState = function( newState ){ this.currState = newState; }
为避免一个对象遗漏方法的 技巧是:
var State = function(){}; State.prototype.buttonWasPressed = function(){ throw new Error('父类的buttonWasPressed方法必须被重写'); } var SupperStrongLightState = function( light ){ this.light = light; } SupperStrongLightState.prototype = new State(); SupperStrongLightState.prototype.buttonWasPressed = function(){ //这里需要重写 }
JavaScript版本的状态机。
JS可以很方便的使用委托技术,并不需要事先让一个对象持有另一个对象。下面的状态机通过Function.prototype.call方法直接把请求委托给某在字面量对象来执行。
var Light = function() { this.currState = FSW.off; //设置当前状态 this.button = null; }; Light.prototype.init = function(){ var button = document.createElement('button'), self = this; this.button = document.body.appendChild( button ); this.button.innerHTML = '已关灯'; this.button.onclick = function(){ self.currState.buttonWasPress.call( self ); } } var FSW = { off:{ buttonWasPress: function(){ console.log('关灯'); this.button.innerHTML = '下一次按我是开灯'; FSW.currState = FSW.on; } }, on:{ buttonWasPress: function(){ console.log('开灯'); this.button.innerHTML = '下一次按我是关灯'; FSW.currState = FSW.off; } } }