从一个页面开关讲讲有限状态机

故事起源于最近看一位朋友在实现一个 播放/暂停 按钮时, 一些思路上的碰撞,
因而整理出本文, 讲解一下如何用 有限状态机 使代码更简洁可靠.

咱们想实现上面这样的按钮交互, 先看看原版实现:app

$('#botton').on('click', function(){
    if ( $(this).text() === 'OFF' ){
        //把按钮的文案改变一下
        $(this).text('ON');
        //开始播放
        $('#player').start();
    } else {
        $(this).text('OFF');
        $('#player').stop();
    }
});

这是一个基本的实现方式, 也是一个最简单的方式.函数

不过,this

按照这个方式来作有几个不太优雅的地方:编码

  • 若是点击按钮以后, 须要作的操做增长, 会让if / else里面的代码愈来愈臃肿.
  • 若是按钮的变化不止 on/off两种, 咱们可能须要些一堆 else if或者用switch / case

针对以上情况, 我提议试试使用有限状态机来解决问题

先看代码:spa

var fsm = (function(){
    //初始状态
    var status = 1; 
    
    //状态对应的操做
    var mapping = {
        '1': {
            text:'ON',
            action: $('#player').start
        },
        '-1': {
            text:'OFF',
            action: $('#player').stop
        },
    };
    
    return function(btn){
        //经过 *-1 实现status从 1/-1 切换
        status *= -1;
        btn.text( mapping[status].text );
        var fn = mapping[status].action;
        fn();
    }
})();

$('#botton').click(function(){
    fsm(this);
});

阅读上面代码能发现, 对botton的点击事件处理, 只须要调用fsm函数便可, 内部的变化和操做, 都不须要暴露出来.code

fsm内部, 经过mapping来定义和限制行为, 惟一可以改变的只有status,事件

这样的好处在于, 可以避免在编码过程当中人为的错误, 由于事件响应部分只能有限的操做状态机的status,而不是直接参与botton的行为与表现.rem

同时, 功能的扩展, 状态的增减, 都只须要在mapping里面定义好, 很是利于扩展与维护.it

相关文章
相关标签/搜索