这一篇文章是关于设计模式大冒险系列的第五篇文章,这一系列的每一篇文章我都希望能够通过通俗易懂的语言描述或者日常生活中的小例子来帮助大家理解好每一种设计模式。
今天这篇文章来跟大家一起学习一下状态模式。相信读完这篇文章之后,你会收获很多。在以后的开发中,如果遇到了类似的情况就知道如何更好地处理,能够少用if
和else
语句,以及switch
语句,写出更已读,扩展性更好,更易维护的程序。话不多说,我们开始今天的文章吧。
开发过程中的一些场景
我们在平时的开发过程中,经常会遇到这样一种情况:就是需要我们处理一个对象的不同状态下的不同行为。比如最常见的就是订单,订单有很多种状态,每种状态又对应着不同的操作,有些操作是相同的,有些操作是不同的。再比如一个音乐播放器程序,在播放器缓冲音乐,播放,暂停,快进,快退,终止等的情况下又对应着各种操作。有些操作在某些情况下是允许的,有些操作是不允许的。还有很多不同的场景,这里就不一一列举了。
那么面对上面说的这些情况我们应该如何设计我们的程序,才能让我们开发出来的程序更好维护与扩展,也更方便别人阅读呢?先别着急,我们一步一步来。遇到这种情况我们应该首先把整个操作的状态图画出来,只有状态图画出来,我们才可以清晰的知道这个过程中会有哪些操作,都发生了哪些状态的改变。只要我们做了这一步,然后按照状态图的逻辑去实现我们的程序;先不管代码的质量如何,至少可以保证我们的逻辑功能是满足了需求的。
生活小例子,我的吹风机
让我们从生活中的一个小例子入手吧。最近我家里新买了一个吹风机,这个吹风机有两个按钮。一个按钮控制吹风机的开关,另一个按钮可以在吹风机打开的情况下切换吹风的模式。吹风机的模式有三种,分别是热风,冷热风交替,和冷风。并且吹风机打开时默认是热风模式。
如果让我们来编写一个程序实现上面所说的吹风机的控制功能,我们应该怎么实现呢?首先先别急着开始写代码,我们需要把吹风机的状态图画出来。如下图所示:
![b5d2540eda3bd0cafc6f146cf59cb27f.png](https://img-blog.csdnimg.cn/img_convert/b5d2540eda3bd0cafc6f146cf59cb27f.png)
上面的状态图已经把吹风机的各种状态都表示出来了,其中圆圈表示了吹风机的状态,带箭头的线表示状态转换。从这个状态图我们可以很直观的知道:吹风机从关闭状态到打开状态默认是热风模式,然后这三种模式可以按照顺序进行切换,然后在每一种模式下都可以直接关闭吹风机。
一般的实现方式
当我们知道了整个吹风机的状态转换之后,我们就可以开始写代码了。我们先按照最直观的方式去实现我们的代码。首先我们知道吹风机有两个按钮,一个控制开关,一个控制吹风机的吹风模式。那么我们的程序中需要有两个变量来分别表示开关状态
和吹风机当前所处的模式
。这一部分的代码如下所示:
function HairDryer() {
// 定义内部状态 0:关机状态 1:开机状态
this.isOn = 0;
// 定义模式 0:热风 1:冷热风交替 2:冷风
this.mode = 0;
}
接下来就要实现吹风机的开关按钮的功能了,这一部分比较简单;我们只需要判断当前isOn
变量,如果是打开状态就将isOn
设置为关闭状态,如果是关闭状态就将isOn
设置为打开状态。需要注意的一点就是在吹风机关闭的情况下需要将吹风机的模式重置为热风模式。
// 切换吹风机的打开关闭状态
HairDryer.prototype.turnOnOrOff = function() {
let { isOn, mode } = this;
if (isOn === 0) {
// 打开吹风机
isOn = 1;
console.log('吹风机的状态变为:[打开状态],模式是:[热风模式]');
} else {
// 关闭吹风机
isOn = 0;
// 重置吹风机的模式
mode = 0;
console.log('吹风机的状态变为:[关闭状态]');