状态模式的关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变。
有预感这个模式和react会十分贴合。
在传统的面向对象的语言中,每种状态都定义了一个状态子类,然后在context中持有这些状态对象的引用,;以便将currState设置为当前的状态。
在js语言中,状态对象不需要从类中创建出来,且在js中有apply和call这种委托技术,一个对象也不需要持有另一个对象的引用(来调用相关方法)。
var Light=function(){
this.currState=FSM.off
this.button=null
}
Light.prototype.init=function(){
var button=document.createElement('button')
self=this // 为啥要这个self,因为下面onclick用到了light的this而不是button的this
button.innerHTML='已关灯'
this.button=document.appendChild(button)
this.button.onclick=function(){
self.currState.buttonWasPressed.call(self)
}
}
// 然后构建出一个状态对象FSM
var 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.offState
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.currState.buttonWasPressed()
}
}
var light=new Light()
light.init()