行为型设计模式之状态模式

99 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情

前言

状态模式是什么鬼?看到的第一眼完全是懵逼的,直到我忍着看完的时候,我才发现原来是它。进行业务开发的时候经常会使用状态模式,只是不知道它就是状态模式而已。

状态模式:当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来像是改变了对象。

可能说到这里还是很抽象,但是,我相信只要我们针对具体的代码一看大家就会发现很熟悉。

探索之旅

这个周我们接到了一个需求,根据冷柜的温度状态来亮起不同的信号灯来通知到工作人员,以方便工作人员对异常情况进行处理。

分支判断

对于这样的情况我们通常的处理方式,一般是通过if...else...进行状态的罗列处理。换句话说,就是实现这个需求有多少种情况,就会衍生出多少的分叉条件。对于简单的逻辑场景来说还好,但是,对于情况较多的时候,会导致内部分支过多,不容易查看和维护。

    function handleTemp (value) {
        if (value === 'normal') {
            // 处理方式
        } else if (value === 'low') {
            // 处理方式
        } eles if (value === 'ultralow') {
            // 处理方式
        } else {
            // 处理方式
        }
    }

swtich条件

对于这种情况,稍微进一步的优化是通过switch进行分支条件的管理。

    function handleTemp (value) {
        switch (value) {
            case 'normal':
                // 处理方式
                break;
            case 'low':
                // 处理方式
                break;
            case 'ultralow':
                // 处理方式
                break;
            default:
                // 处理方式
        }
    }

实际上,对于这种复杂情况来说,通过if...else...分支判断和使用switch条件语句来判断是基本没有太大区别的。除了语法上稍微清晰一些外,对于代码的可读性和可维护性来说,没有太大的优化效果。

所以我们就需要通过我们的状态模式对这种多情况的状态判断进行包装处理。

状态模式

要想使用状态模式,我们先要将所有的状态统一封装到一个状态对象中去,然后再通过key来获取对象的值进行调用。粗糙一点的代码如下:

    function handleTemp (value) {
        const tempState = {
            'normal': () => {
                // 处理方式
            },
            'low': () => {
                // 处理方式
            },
            'ultralow': () => {
                // 处理方式
            },
            'default': () => {
                // 处理方式
            },
        }
        
        (tempState[value] || tempState['default'])();
    }

怎么样?是不是很意外,没想到这就是所谓的状态模式吧!

通过这种方式的话,我们就可以针对每种状态进行处理,实现状态与状态之间的解耦。 当然,这样的处理方式可以解决相当一部分问题了。但是,对于这种依赖于object的方式来说,对于复杂的条件判断方式来说,是解决不了问题的。不过,幸好ES6中提供了新的数据类型Map,我们可以结合Map数据类型进行更复杂的数据存储方式,这样的话,我们就可以来实现更复杂的状态模式了。

结语

好了,有关状态模式的内容我们就聊到这里了,希望能对大家有所帮助。

欢迎大家在下方进行留言交流。