状态模式
定义
状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类,类的行为随着它的状态改变而改变。
当程序需要根据不同的外部情况来做出不同操作时,最直接的方法就是使用 switch-case 或 if-else 语句将这些可能发生的情况全部兼顾到,但是这种做法应付复杂一点的状态判断时就有点力不从心,开发者得找到合适的位置添加或修改代码,这个过程很容易出错,这时引入状态模式可以某种程度上缓解这个问题。
优缺点
状态模式的优点:
- 结构相比之下清晰,避免了过多的 switch-case 或 if-else 语句的使用,避免了程序的复杂性提高系统的可维护性;
- 符合开闭原则,每个状态都是一个子类,增加状态只需增加新的状态类即可,修改状态也只需修改对应状态类就可以了;
- 封装性良好,状态的切换在类的内部实现,外部的调用无需知道类内部如何实现状态和行为的变换。
状态模式的缺点:
- 引入了多余的类,每个状态都有对应的类,导致系统中类的个数增加。
适用场景
- 操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态,那么可以使用状态模式来将分支的处理分散到单独的状态类中;
- 对象的行为随着状态的改变而改变,那么可以考虑状态模式,来把状态和行为分离,虽然分离了,但是状态和行为是对应的,再通过改变状态调用状态对应的行为;
示例
var State = function(){
this.currentState = FSM.state1;
this.btn = null;
};
State.prototype.init = function(){
var self = this;
this.btn = document.getElementById("btn");
this.btn.onclick = function() {
self.currentState.buttonWasPressed.call(self);
};
}
var FSM = {
state1: {
buttonWasPressed: function(){
console.log("state1");
this.btn.innerHTML = "state2";
this.currentState = FSM.state2;
}
},
state2: {
buttonWasPressed: function(){
console.log("state2");
this.btn.innerHTML = "state3";
this.currentState = FSM.state3;
}
},
state3: {
buttonWasPressed: function(){
console.log("state3");
this.btn.innerHTML = "state1";
this.currentState = FSM.state1;
}
}
}
var state = new State();
state.init();