Javascript设计模式 - 18 - 状态模式
简介
状态模式的关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变
通常我们谈到封装,一般都会优先封装对象的行为,而不是对象的状态,但在状态模式中刚好相反,状态模式的关键是把事物的每种状态都封装成单独的类,跟此种状态有关的行为都被封装在这个类的内部,执行上下文中,请求直接委托给状态对象,该状态对象会负责渲染它自身的行为
定义
允许一个对象在其内部状态改变时改变他的行为,对象看起来似乎修改了它的类
将状态封装成独立的类,并将请求委托给当前的状态对象,当对象内部状态改变时,会带来不同的行为变化
我们使用对象,在不同的状态下会有不同的行为,这个对象看起来是从不同的类中实例化来的,实际上使用的是委托的效果
优缺点
- 状态模式定义了状态与行为之间的关系,并将他们封装在一个类中,通过增加新的状态类,很容易增加新的状态和转换
- 避免执行上下文 Context 无线膨胀,切换状态的逻辑被分布在状态类中,也去掉了 Context 中原本过多的条件分支
- 用对象代替字符串记录当前状态,使得状态的切换更加的一目了然
- 缺点是会在系统中定义许多的状态类和对象,另外由于逻辑分散在状态类中,造成了逻辑分散的问题,无法在一个地方看出整个状态机的逻辑
// 定义状态类
var FSM = {
off: {
// 状态对应的行为
buttonWasPressed: function () {
console.log('关灯');
this.button.innerHTML = '下次开灯';
// 定义好要切换到的下一个状态
this.currState = FSM.on;
}
},
on: {
buttonWasPressed: function () {
console.log('开灯');
this.button.innerHTML = '下次关灯';
this.currState = FSM.off;
}
}
}
var Light = function () {
// 设置初始状态
this.currState = FSM.off;
this.button = null;
}
Light.prototype.init = function () {
var button = document.createElement('button');
var self = this;
button.innerHTML = '已关灯'
this.button = document.body.appendChild(button);
this.button.onclick = function () {
self.currState.buttonWasPressed.call(self);
}
}
var light = new Light();
light.init();
状态模式和策略模式
共同点:都封装了一系列的算法或者行为,都有一个上下文、一些策略或者状态类,上下文把请求委托给这些类来执行
不同点:策略模式中,的各个策略类是平等又平行的,他们之间没有任何联系,算法切换是用户主动完成的;而在状态模式中,状态和状态对应的行为是早已被封装好的,状态之间的切换也早被规定完成,“改变行为”这件事情发生在状态模式内部,客户不需要了解这些细节
文章列表
- javascript设计模式 – 设计原则
- JavaScript设计模式–高阶函数
- Javascript 设计模式 - 01 - 原型模式
- Javascript 设计模式 - 02 - 单例模式
- Javascript 设计模式 - 03 - 建造者模式
- Javascript 设计模式 - 04 - 工厂模式
- Javascript 设计模式 - 05 - 外观模式
- Javascript 设计模式 - 06 - 代理模式
- Javascript 设计模式 - 07 - 观察者模式(发布订阅模式)
- Javascript 设计模式 - 08 - 策略模式
- Javascript 设计模式 - 09 - 命令模式
- Javascript 设计模式 - 10 - 迭代器模式
- Javascript 设计模式 - 11 - 职责链模式
- Javascript 设计模式 - 12 - 适配器模式
- Javascript 设计模式 - 13 - 模板方法
- Javascript 设计模式 - 14 - 组合模式
- Javascript 设计模式 - 15 - 享元模式
- Javascript 设计模式 - 16 - 中介者模式
- Javascript 设计模式 - 17 - 装饰者模式
- Javascript 设计模式 - 18 - 状态模式