状态模式,指的是事物内部状态的变化,会导致事物具体行为的变化。并且,状态的切换可以是循环的。最简单的例子是生活中的开关,基本都是状态模式的使用。
一、利用实例对象的切换
// 定义灯类
var Light = function () {
this.currState = stateManager.off; // 灯的状态
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.changeState.call(self); // 把请求委托给 stateManager 状态机
}
};
// 定义灯的状态管理对象
var stateManager = {
off: {
changeState: function () {
this.button.innerHTML = '开灯';
this.currState = stateManager.on;
}
},
on: {
changeState: function () {
this.button.innerHTML = '关灯';
this.currState = stateManager.off;
}
}
};
// 实例化灯
var light = new Light();
// 登初始化
light.init();
在当前例子中,首先定义灯类Light,其中有属性currState表示当前状态,button表示开关。定义的init方法会首先创建开关,再为开关绑定切换开关状态的函数changeState。
定义的状态管理对象中包含属性off和on的具体行为对象,每个行为的执行都是通过其中的changeState函数来实现,该函数触发时就会将当前灯的状态进行切换。
2、利用数组的有序性
// 定义灯的类
var Light = function () {
this.currentIndex = 0; // 设置初始索引
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 () {
excuteStateFn(self);
}
};
// 定义状态状态切换列表
var stateList = [
function changeState(light) {
light.button.innerHTML = '开灯';
},
function changeState(light) {
light.button.innerHTML = '关灯';
}
]
// 定义状态切换执行函数
function excuteStateFn(light) {
light.currentIndex >= stateList.length && (light.currentIndex = 0); // 进行边界状态的控制
stateList[light.currentIndex++](light) // 切换状态
}
// 实例化灯
var light = new Light();
// 灯进行初始化
light.init();
在当前例子中,首先定义灯类Light,其中有属性currentIndex表示行为对应的索引,button表示开关。定义的init方法会首先创建开关,再为开关绑定切换开关状态的函数excuteStateFn(self)。
定义的状态切换列表中stateList包含数组元素off和on的具体行为函数。
再定义行为切换执行函数excuteStateFn,每个行为的执行都是通过执行当前索引对应的行为函数stateList[light.currentIndex++](light)来实现的,通过修改当前索引的值来切换下一次执行的状态索引。
总结
状态模式的实现不止一种实现思路,可以利用行为函数执行时修改当前实例对象的状态实现,也可以利用数组天然的有序性通过索引的改变指向对应的执行函数,当然,还可能有其他实现方式。只要遵循状态模式
状态的切换可以是循环的,任何实现都是正确的。