状态模式的关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变。
有预感这个模式和react会十分贴合。
在传统的面向对象的语言中,每种状态都定义了一个状态子类,然后在context中持有这些状态对象的引用,;以便将currState设置为当前的状态。
在js语言中,状态对象不需要从类中创建出来,且在js中有apply和call这种委托技术,一个对象也不需要持有另一个对象的引用(来调用相关方法)。
var Light=function(){this.currState=FSM.offthis.button=null}Light.prototype.init=function(){var button=document.createElement('button')self=this // 为啥要这个self,因为下面onclick用到了light的this而不是button的thisbutton.innerHTML='已关灯'this.button=document.appendChild(button)this.button.onclick=function(){self.currState.buttonWasPressed.call(self)}}// 然后构建出一个状态对象FSMvar FSM={off:{buttonWasPressed:function(){console.log('关灯')this.button.innerHTML='开灯'this.currState=FSM.on}},on:function(){...}}
另一种写法,利用delegate函数来编写状态机
var delegate=function(client,delegation){return {buttonWasPressed:function(){return delegation.buttonWasPressed.apply(client,arguments)}}}var FSM={// 同上面那个状态机}var Light=function(){this.offState=delegation(this,FMS.off)this.onState=delegation(this,FMS.on)this.currState=this.offStatethis.button=null}// 初始化Light.prototype.init=function(){var button=document.createElement('button')self=thisbutton.innerHTML='已关灯'this.button=document.body.appendChild('button')this.button.onclick=function(){self.currState.buttonWasPressed()}}var light=new Light()light.init()
