我想学会设计模式之状态模式
这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战
状态模式:对象行为是
根据状态改变,而改变的。
什么是“状态模式”?
状态模式:对象行为是根据状态改变,而改变的。
正是由于内部状态的变化,导致对外的行为发生了变化。例如:相同的方法在不同时刻被调用,行为可能会有差异。
优缺点
优点:
- 封装了
转化规则,对于大量分支语句,可以考虑使用状态类进一步封装。 - 每个
状态都是确定的,对象行为是可控的。 - 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
- 可以让
多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点:
- 状态模式的实现关键是将事物的状态都封装成单独的类,这个类的各种方法就是“此种状态对应的表现行为”。因此,程序开销会增大。
会增加系统类和对象的个数,且结构与实现都较为复杂。状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式
应用实例
- 打篮球的时候运动员可以有正常状态、不正常状态和超常状态。
- 曾侯乙编钟中,'钟是抽象接口','钟A'等是具体状态,'曾侯乙编钟'是具体环境(Context)。
代码实现
ES6 实现
在 JavaScript 中,可以直接用 JSON 对象来代替状态类。
下面代码展示的就是 FSM(有限状态机)里面有 3 种状态:download、pause、deleted。控制状态转化的代码也在其中。
DownLoad类就是,常说的Context对象,它的行为会随着状态的改变而改变。
const FSM = (() => {
let currenState = "download";
return {
download: {
click: () => {
console.log("暂停下载");
currenState = "pause";
},
del: () => {
console.log("先暂停, 再删除");
}
},
pause: {
click: () => {
console.log("继续下载");
currenState = "download";
},
del: () => {
console.log("删除任务");
currenState = "deleted";
}
},
deleted: {
click: () => {
console.log("任务已删除, 请重新开始");
},
del: () => {
console.log("任务已删除");
}
},
getState: () => currenState
};
})();
class Download {
constructor(fsm) {
this.fsm = fsm;
}
handleClick() {
const { fsm } = this;
fsm[fsm.getState()].click();
}
hanldeDel() {
const { fsm } = this;
fsm[fsm.getState()].del();
}
}
// 开始下载
let download = new Download(FSM);
download.handleClick(); // 暂停下载
download.handleClick(); // 继续下载
download.hanldeDel(); // 下载中,无法执行删除操作
download.handleClick(); // 暂停下载
download.hanldeDel(); // 删除任务