状态模式案例分析

来源:互联网 发布:每周开户数据 编辑:程序博客网 时间:2024/06/06 07:43

需求

初始状态下,【暂停按钮】不可点,所有数轴可调:

这里写图片描述

点击【动态波】后,【暂停按钮】可点,所有数轴可调:

这里写图片描述

点击【暂停按钮】后,“暂停”变为“播放”,所有数轴不可调:

这里写图片描述

分析需求

上面的需求很明显可以分为三个状态:初始状态、波动状态、暂停状态。不同的状态下,同一个按钮的表现不一样,比如暂停按钮,在初始状态下不可点,在其它状态下可点。

其实判断是否使用状态模式也是这样考虑:看同一个对象,在整个生命周期中,对同一个事件是否有多种响应。如果有的话,那这个对象就存在多个状态。如果多个对象都有某几个状态(比如都有播放,暂停状态),那就可以考虑使用状态模式了。

使用状态模式的好处是,可以消除分散各处的状态判断的代码。

实现代码

  • 不使用状态模式:
class DomEvent{   stop(e){     if(this.state === 'waving'){        //处理波动状态     }else if(this.state === 'stop'){        //处理暂停状态     }else{       //处理初始状态     }   }   /**     * 点击波长数轴     */    clickWave(e){        if(this.state === 'stop'){            return;        }        //...    }}
  • 使用状态模式
export default class DomEvent{    //单例    static _inst;    static getInst(){        DomEvent._inst = DomEvent._inst || new DomEvent();        return DomEvent._inst;    }    constructor(){}    init(){        this.stateList = {            "default" : new DefaultState(),            "waving" : new WavingState(),            "stop" : new StopState()        }        this.state = this.stateList["default"];        return this;    }    /**     * 修改状态     */    changeState(stateName){        this.state = this.stateList[stateName];    }    stop(e){        this.state.stop(e);    }    /**     * 点击波长数轴     */    clickWave(e){        this.state.clickWave(e);    }}

具体的状态类可以这样写:

export default class StopState{    constructor(){        this.domEvents = DomEvent.getInst();    }    stop(e){        this.stopBtn.text("播放");        this.domEvents.changeState('waving');    }    /**     * 点击波长数轴     */    clickWave(e){        //...    }}

这样,每个状态下该做什么,一目了然。

0 0
原创粉丝点击