状态模式

作者: 小宇cool | 来源:发表于2020-11-03 22:07 被阅读0次

    1.状态模式

    1.1 定义

    状态模式(State pattem) : 当对象内部状态发生了改变,它的行为也对应的发生改变, 使之看起来像是改变了这个对象

    当需求有多个状态,并在某些条件下会从一种状态变成另一种状态时,并且对象的行为依赖它的状态, 使用状态模式就非常合适.状态模式和命令模式一样,都用于消除 if...else 等条件选择语句。

    1.2 作用

    1. 解决当代码中有过多的条件,分支语句时带来的维护困难问题
    2. 将对象的行为和对应的状态的结构变得更加清晰,便于阅读理解.
    3. 便于扩展,添加新的的状态和对应的行为.

    1.3应用场景

    • 场景一 开关灯的切换
    //普通写法
    //这是一个只有两个状态的模型,多个状态写法也是一样的
    let Switch = document.querySelector(".Switch");
    let displayer = document.querySelector(".displayer");
    let state = "off";
    function switchFn{
        if( state === "off" ){
            state = "on";
            displayer.textContent = '开启'
        }else if( state === "on" ){
            state = "off";
             displayer.textContent = '关闭'
        }
    };
    Switch.onclick = switchFn;
    

    上面的代码是一个状态模式很简单的应用场景, 但是当我们某个状态对应的代码需要修改,或者添加新的状态, 我们就得修改整个switchFn, 显然这样很麻烦, 当我们的状态越来越多时,写起来非常模式, 状态和对应的行为模块之间不够独立,很显然这不是一个稳定的方法, 违背了开闭原则,我们可以将这种状态模式的代码写的更加优雅好看一点.

    const displayer = document.querySelector('.displayer'), 
      // 状态管理容器
    let StateMachine = {
        FSM:{// 状态机
            top:{
                to:'center',
                action(){
                    console.log('状态从top变为center');
                    displayer.innerText = 'center';
                }
            },
            center:{
                to:'bottom',
                action(){
                    console.log('状态从center变为bottom');
                     displayer.innerText = 'bottom';
                }
            },
            bottom:{
                to:'top',
                action(){
                    console.log('状态bottom变为top');
                     displayer.innerText = 'top';
                }
            }
        },
        // 当前状态
        currentState:'top',
        transitionState(){
            // 获取当前状态的信息
            let State = this.FSM[this.currentState];
            // 改变当前状态
            this.currentState = State.to;
            // 执行当前状态所对应的操作
            State.action()
        },
        init(){
            let Switch = document.querySelector('.switch');
            Switch.onclick = ev => {
                this.transition()
            }
         }
    }
    StateMachine.init()
    

    上面的代码中我们通过状态机FSM来保存每个状态对应的要切换的状态值以及对应的操作,通过currentState来保存所处的状态, 以便获取当前切换的状态, 利用transitionState来进行切换状态以及调用对应的执行动作.这样代码看上去更加优雅,便于维护, 降低了状态和状态切换之间的强耦合关系.

    这是一个有限状态机的js库, 可以让我们非常方便的创建状态模式.

    通过 npm安装

     npm install --save-dev javascript-state-machine
    

    通过浏览器引入

     <script src='state-machine.js'></script>
    

    下面是一个简单的实例

    var fsm = new StateMachine({
        init: 'solid',
        transitions: [
          { name: 'melt',     from: 'solid',  to: 'liquid' },
          { name: 'freeze',   from: 'liquid', to: 'solid'  },
          { name: 'vaporize', from: 'liquid', to: 'gas'    },
          { name: 'condense', from: 'gas',    to: 'liquid' }
        ],
        methods: {
          onMelt:     function() { console.log('I melted')    },
          onFreeze:   function() { console.log('I froze')     },
          onVaporize: function() { console.log('I vaporized') },
          onCondense: function() { console.log('I condensed') }
        }
      });
    

    总结: 当对象的行为依赖于它的状态, 对应的操作会改变状态,并且状态可能越来越多时, 对应的操作越来越复杂时, 如果我们使用大量的判断操作,此时if-else的分支可能会越来越多,并且越来越复杂, 此时我们使用状态模式就可以极大优化我们代码的结构,使代码更易于维护.

    相关文章

      网友评论

        本文标题:状态模式

        本文链接:https://www.haomeiwen.com/subject/atzivktx.html