状态模式
1.状态模式
1.1 定义
状态模式(State pattem) : 当对象内部状态发生了改变,它的行为也对应的发生改变, 使之看起来像是改变了这个对象
当需求有多个状态,并在某些条件下会从一种状态变成另一种状态时,并且对象的行为依赖它的状态, 使用状态模式就非常合适.状态模式和命令模式一样,都用于消除 if...else 等条件选择语句。
1.2 作用
解决当代码中有过多的条件,分支语句时带来的维护困难问题
将对象的行为和对应的状态的结构变得更加清晰,便于阅读理解.
便于扩展,添加新的的状态和对应的行为.
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来进行切换状态以及调用对应的执行动作.这样代码看上去更加优雅,便于维护, 降低了状态和状态切换之间的强耦合关系.
场景二-- Javascript Finite State Machine
这是一个有限状态机的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的分支可能会越来越多,并且越来越复杂, 此时我们使用状态模式就可以极大优化我们代码的结构,使代码更易于维护.
作者:小宇cool
链接:https://www.jianshu.com/p/adaccbdbbeec
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。