状态模式
状态模式允许一个对象在其内部状态改变的时候改变它的行为,对象看起来似乎修改了它的类
1 2 3 4
| const obj = { state: '' action(){} }
|
对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为
简单实现
王者荣耀就可能同时有好几个状态(攻击,移动,回城,死亡)等
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const change = state => { if (state == '攻击') { console.log('攻击') } else if (state == '移动') { console.log('移动') } else if (state == '回城') { console.log('回城') } else if (state == '死亡') { console.log('泉水看戏') } }
change('攻击')
|
如果对这些动作进行处理判断,需要一堆 if-else 或者 switch,当遇到有组合动作的时候(边走边 A),实现起来就会变的更为复杂。
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
| class kingGlory { constructor() { this._currentState = [] this.states = { attack() { console.log('攻击') }, move() { console.log('移动') }, back() { console.log('回城') }, death() { console.log('泉水看戏') } } }
change(arr) { this._currentState = arr return this }
go() { this._currentState.forEach(T => this.states[T] && this.states[T]()) return this } }
new kingGlory().change(['move']).go()
|
状态模式的思路是:首先创建一个状态对象保存状态变量,然后封装好每种动作对应的状态,然后状态对象返回一个接口对象,它可以对内部的状态修改或者调用。
使用场景
滚动加载,包含了初始化加载、加载成功、加载失败、滚动加载等状态,任意时间它只会处于一种状态

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 44 45 46 47 48 49 50
| class rollingLoad { constructor() { this._currentState = 'init' this.states = { init: { failed: 'error' }, init: { complete: 'normal' }, normal: { rolling: 'loading' }, loading: { complete: 'normal' }, loading: { failed: 'error' }, } this.actions = { init() { console.log('初始化加载,大loading') }, normal() { console.log('加载成功,正常展示') }, error() { console.log('加载失败') }, loading() { console.log('滚动加载') } } }
change(state) { let to = this.states[this._currentState][state] if(to){ this._currentState = to this.go() return true } return false }
go() { this.actions[this._currentState]() return this } }
|
vue 中的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // 使用 mounted(){ rollingLoad.go() }
methods:{ getData(){ this.$api.xxxAPI.getXXX().then(res=>{ if(res.code == 0){ rollingLoad.change('complete') } else { rollingLoad.change('failed') } }) }, rolling(){ rollingLoad.change('loading') }, }
|
总结
- 代码中包含大量与对象状态有关的条件语句(if else或switch case),且这些条件执行依赖于该对象的状态
- 对象的行为取决于它的状态,状态之间存在联系
状态模式和策略模式的区别
1.策略类的各个属性之间是平等平行的,它们之间没有任何联系
2.状态机中的各个状态之间存在相互切换,且是被规定好了的。