1、模式定义
状态模式,当一个对象的内部状态发生改变时,这会导致其行为的改变。这看起来像是改变了对象。
2、为什么需要状态模式?它能解决什么问题?
状态模式,主要目的就是把条件判断的不同结果,转化为状态对象的内部状态,然后提供一个能够调用该对象的内部状态的接口方法。如此,我们就能够方便地增加、修改、调用和删除这个对象的内部状态,帮助我们更好地管理这个对象的内部状态。
像如下的代码,即是根据对象的不同状态来执行不同的功能逻辑。这种使用条件判断来实现的方式,非常不便于后期的维护,当有状态需要增、删、改时,就会遇到一系列麻烦。
function showResult(result) {
if (result == 0) {
// 执行功能1
} else if (result == 1) {
// 执行功能2
} else if (result == 2) {
// 执行功能3
}
}
3、使用状态模式 来优化使用条件判断实现的状态分支
下面代码就是状态模式的雏形,这样我们就可以方便地修改、增加、调用和删除对象的内部状态。这比使用条件语句实现的状态分支具有更多的优势。
var ResultState = function() {
var States = {
state0: function() {
console.log('这是对象的第一种状态');
},
state1: function() {
console.log('这是对象的第二种状态');
},
state2: function() {
console.log('这是对象的第三种状态');
},
state3: function() {
console.log('这是对象的第四种状态');
},
state4: function() {
console.log('这是对象的第五种状态');
}
}
function show(result) {
// 如果存在该状态,就执行其对应的功能逻辑
States['state' + result] && States['state' + result]();
}
return { show: show }
}();
// 小测一下:执行第四种状态
ResultState.show(3);
4、状态模式 举例
// 状态模式:超级玛丽的状态模式
var MarryState = function() {
// 当前状态
var _curState = {};
// 默认的四种状态
var states = {
jump: function() {
console.log('超级玛丽 在跳跃');
},
move: function() {
console.log('超级玛丽 在移动');
},
shoot: function() {
console.log('超级玛丽 在躲击');
},
squat: function() {
console.log('超级玛丽 已蹲下');
}
};
// 状态控制
var Action = {
// 改变对象内部状态
changeState: function() {
var arg = arguments;
_curState = {};
if (arg.length) {
for (var i=0; i<arg.length; i++) {
_curState[arg[i]] = true;
}
}
return this;
},
// 执行一遍功能逻辑
goes: function() {
console.log('触发一次动作');
for (var i in _curState) {
states[i] && states[i]();
}
return this;
}
}
return {
change: Action.changeState,
goes: Action.goes
}
}
现在,我们已经把超级玛丽的状态模式创建出来了。我们有两种方式来使用它。
// 使用方式一
MarryState().change('jump', 'shoot') // 改变对象内部状态
.goes() // 执行动作
.goes()
.change('shoot') // 改变对象内部状态
.goes();
// 使用方式二
var marry = new MarryState();
marry.change('jump', 'shoot') // 改变对象内部状态
.goes()
.goes()
.change('shoot') // 改变对象内部状态
.goes();
像这样,改变对象的状态变得如此简单,状态一旦改变其行为结果立即改变。并且思路是非常清晰的。
5、小结
使用状态模式,我们可以把条件判断中的每一种情况独立出来进行管理,解决了分支条件之间的耦合问题。
状态模式既能解决程序中臃肿的分支判断语句,还能把每个分支转化成一种独立的状态,并方便每种状态的管理。程序产出何种结果,取决于用户选择了哪种状态,而选择状态又是在程序运行时被决定的。
END 2019-03-01
网友评论