状态模式:
将对应的状态信息和状态变化保存在各自的类中,在主控制的类中,只需对所有的状态进行初始化即可,这样可一眼在构造函数中看出有多少种状态变化,避免了在主类中编写过多的if, else 条件语句来控制状态的变化,同时符合了代码的开放-封闭原则。
那么什么是状态?
状态在日常生活中很常见,比如看电视时遥控器的按钮对应着暂停和播放,第一次按下按钮暂停,再按下即播放。暂停和播放就是相应的状态。
最近买了电动牙刷,有这3种状态,开始按下即启动了默认模式 ,再次按下会变成敏感模式, 第三次按下即是关闭状态。如下图所示:
采用状态模式实现代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| class OffState { constructor(toothbrush){ this.toothbrush = toothbrush; } clickButton() { console.log('电动牙刷启动'); this.toothbrush.set(this.toothbrush.onState); } } class OnState { constructor(toothbrush){ this.toothbrush = toothbrush; } clickButton() { console.log('刷牙模式切换为敏感模式'); this.toothbrush.set(this.toothbrush.sensitiveState); } }
class SensitiveState { constructor(toothbrush){ this.toothbrush = toothbrush; } clickButton() { console.log('电动牙刷关闭'); this.toothbrush.set(this.toothbrush.offState); } }
class ElecToothbrush { constructor(){ this.onState = new OnState(this); this.offState = new OffState(this); this.sensitiveState = new SensitiveState(this); this.curState = this.offState; }
set(newState){ this.curState = newState; } }
var tb = new ElecToothbrush();
|
将tb实例上当前状态的clickButton事件绑定到button上,
1 2
| <button onclick="tb.curState.clickButton()">开关</button>
|
打开控制台可以看见每按一次button,就会显示相应的状态变化。
如果不采用状态模式实现,那么在主类toothbrush中会有个click方法在切换对应的状态实现,就像下面这样会有很多if,else语句分支,如果未来再添加新的状态模式,则又需要添加相应的分支,之后该函数会变得越来越大,同时维护麻烦。
1 2 3 4 5 6 7 8 9 10
| if(this.state==='off'){ console.log('牙刷启动默认模式'); this.state='on'; }else if(this.state==='on'){ console.log('sensitive mode'); this.state='senstive'; } else if(this.state === 'senstive'){ console.log('off'); this.state = 'off'; }
|