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来进行切换状态以及调用对应的执行动作.这样代码看上去更加优雅,便于维护, 降低了状态和状态切换之间的强耦合关系.
这是一个有限状态机的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的分支可能会越来越多,并且越来越复杂, 此时我们使用状态模式就可以极大优化我们代码的结构,使代码更易于维护.
网友评论