一、状态模式定义:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
二、状态模式的关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变。
三、如下有一个比较好的实例,代码如下:
var delegate = function(client, delegation){
return{
buttonWasPressed: function(){ //将客户的操作委托给delegation对象
return delegation.buttonWasPressed.apply(client, arguments );
}
}
};
var FSM = {
off: {
buttonWasPressed: function(){
console.log('关灯');
this.button.innerHTML = '下一次按我是开灯';
this.currState = this.onState;
}
},
on:{
buttonWasPressed: function(){
console.log('开灯');
this.button.innerHTML = '下一次按我是关灯';
this.currState = this.offState;
}
}
};
var Light = function(){
this.offState = delegate( this, FSM.off );
this.onState = delegate( this, FSM.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();
四、状态模式的优缺点:
1、优点:
A、定义了状态与行为之间的关系,并将它们封装在一个类里。通过增加新的状态类,很容易增加新的状态和转换。
B、避免 Context 无限膨胀,状态切换的逻辑被分布在状态类中,也去掉了 Context 中原本过多的条件分支。
C、用对象代替字符串来记录当前状态,使得状态的切换更加一目了然。
D、Context 中的请求动作和状态类中封装的行为可以非常容易地独立变化而互不影响。
2、缺点:
A、在系统中定义许多状态类,而且系统中会因此而增加不少对象。
B、由于逻辑分散在状态类中,虽然避开了不受欢迎的条件分支语句,但也造成了逻辑分散的问题,我们无法在一个地方就看出整个状态机的逻辑。