前言
同学们,上一章我们介绍了装饰者模式,装饰者模式可以在不影响原类的情况下,给对象新增额外的功能,并且我们也尝试了使用AOP面向切面去拓展function的原型来实现装饰者模式。这一章,我们将进一步学习一种新的设计模式,状态模式。
正文
状态模式的定义
允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎改变了它的类
通常对于一般的设计模式,我们的关注点集中在对象的行为上,而不是对象的状态上,而状态模式相反,状态模式是一种封装对象的状态的设计模式。状态模式的关键在于区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变。
状态模式的实现
引入一个很常见的场景,比如我们需要拿代码实现一个电灯开关的场景,我相信大部分同学的想法一定是用一个标识量去标识这个状态,根据标识量的切换,来切换电灯的状态,但是这种写法隐藏着一个问题,如果这盏电灯不止有两个状态,比如像酒店里一些灯可能还有旋转一闪一闪的效果,这时候就体现出了状态模式的优势,我们封装所有的状态模式,再对电灯的状态切换进行维护就可以了
这里我们为了方便后面的实现,不妨假设这盏灯有三种模式,强光,弱光和关闭,按之前说的我们先封装一下这三种状态的类型
var OffLightState = function(light) {
this.light = light;
}
OffLightState.prototype.buttonWasPressed = function() {
console.log('弱光'); // 切换到弱光
the.light.setState(this.light.weakLightState);
}
var WeakLightState = function(light) {
this.light = light;
}
WeakLightState.prototype.buttonWasPressed = function() {
console.log('弱光'); // 切换到强光
the.light.setState(this.light.strongLightState);
}
var StrongLightState = function(light) {
this.light = light;
}
StrongLightState.prototype.buttonWasPressed = function() {
console.log('关灯'); // 切换到关灯
the.light.setState(this.light.offLightState);
}
然后我们再封装一下飞机类即可,在飞机类中为每个状态都创建一个状态对象,至于每个状态所做的行为操作我们只要委托给对应的状态类即可
var Light = function() {
this.offLightState = new OffLightState(this);
this.weakLightState = new WeakLightState(this);
this.strongLightState = new StrongLightState(this);
this.button = null;
}
Light.prototype.init = function() {
this.curState = this.offLightState;
}
Light.prototype.setState = function(newState) {
this.curState = newState;
this.curState.buttonWasPressed();
}
状态模式的优缺点
从上面的例子我们不难发现状态模式的优点:
- 状态模式定义了状态和行为之间的关系,并将它们封装在类里,我们可以更加简单地新建新的状态和行为,符合开放-封闭原则
- 避免主类因状态过多而导致地过度膨胀,状态的定义被分散到状态类中,并且也避免了主类中出现大量条件语句的问题
- 用对象代替字符串表现状态,使得状态的切换更加一目了然
但是状态模式也有一个明显的缺点,它会定义很多额外的状态类,逻辑被分散在状态类中,系统中也会因此增加不少额外的对象
小结
今天我们学习了一种新的设计模式,状态模式,一般设计模式分离对象的行为,而状态模式不同,状态模式的关注点在于对象的状态,将对象的状态单独抽出维护,以避免主类的逻辑过于臃肿的情况
小伙伴们今天的学习就到这里了,如果觉得本文对你有帮助的话,欢迎转发,评论,收藏,点赞!!!
每天学习进步一点点,就是领先的开始。如果想继续提高,欢迎关注我,或者关注公众号”祯民讲前端“。大量前端技术文章,面试资料,技巧等助你更进一步!