状态机模式
特点
- 一个对象有状态变化,--且状态变化是有序且已知的--
- 每次状态变化都会触发一个逻辑
- 不能总是用 if...else 来控制
介绍
-
状态:在代码执行过程中,若存在有标志性的特征的修改引起程序流程的改变。这个特征就是状态
-
状态模式将各种状态封装成一个个的类,并将状态的转变也封装在内。即这种状态的切换是已经固定好的,
-
不会有意外情况导致改变。状态模式节省了主程序中对于现有状态以及下一个状态的循环判断。在新增一种状态时,只需要新增一个状态类,并将状态转换关系在状态类内进行修改就可以。不需要对主程序进行修改。也就是状态的转变对与主程序透明化。主程序只要根据不同的状态进行不同的操作就可以,而不必考虑各种状态之间的转换
-
状态模式在特定环境中,效果明显。比如,程序根据用户的动作做出不同的相应,而这个动作又是多次被触发的时候,可以使用状态模式。
demo
- 状态机工厂优化 详见 /demo/10_状态机模式/状态机工厂模式
// 创建 开灯状态
function LigthOnState(light) {
this.state = "开灯";
this.light = light;
}
// 创建 关灯 状态
function LightOffState(light) {
this.state = "关灯";
this.light = light;
}
function LightStrongState(light) {
this.state = "强光灯";
this.light = light;
}
LigthOnState.prototype.handleButtonClick = function () {
console.log("已开强光灯!");
this.light.setState(this.light.strongState);
};
LightStrongState.prototype.handleButtonClick = function () {
console.log("已关灯");
this.light.setState(this.light.offState);
};
LightOffState.prototype.handleButtonClick = function () {
console.log("已开灯!");
this.light.setState(this.light.onState);
};
function Light() {
this.onState = new LigthOnState(this);
this.strongState = new LightStrongState(this);
this.offState = new LightOffState(this);
this.currentState = null;
console.log("构建 light");
}
Light.prototype.setState = function (state) {
this.currentState = state;
};
Light.prototype.connect = function (btn) {
const _self = this;
this.currentState = this.offState;
btn.click = function () {
_self.currentState.handleButtonClick();
};
console.log(
`light 与 btn 已建立关系,当前 light 状态为 ${this.currentState.state}`
);
};
function Button() {
console.log("构建 btn");
}
const light = new Light();
const btn = new Button();
light.connect(btn);
btn.click(); // 开灯
btn.click(); // 强光灯
btn.click(); // 关灯