状态模式

状态模式: 可以解决程序中臃肿的分支判断语句问题, 将每个分支转化为一种状态独立出来, 方便每种状态的管理又不至于每次执行时遍历所有分支. 在程序中到底产出哪种行为结果, 决定于选择哪种状态, 而选择何种状态又是在程序运行时决定的. 最终目的是简化分支判断流程.

简单的状态对象的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 投票结果状态对象
var Resultstate = (function () {
// 判断结果保存在内部状态中
var states = {
state0: function () {
console.log('state0')
},
state1: function () {
console.log('state1')
},
state2: function () {
console.log('state2')
},
}
// 获取某一种状态 并执行其对应方法
function show(result) {
states['state' + result] && states['state' + result]()
}
return {
show,
}
})()
Resultstate.show(1)

超级玛丽

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
51
52
53
54
// 创建超级玛丽状态类
var Marrystate = function () {
// 内部状态私有变量
var _currentstate = {}
// 动作与状态方法映射
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
// 重置内部状态
_currentstate = {}
// 如果有动作则添加动作
if (arg.length) {
// 遍历动作
for (var i = 0, len = arg.length; i < len; i++) {
// 向内部状态中添加动作
_currentstate[arg[i]] = true
}
}
// 返回动作控制类
return this
},
// 执行动作
goes: function () {
console.log('触发一次动作')
// 遍历内部状态保存的动作
for (var i in _currentstate) {
// 如果该动作存在 则执行
states[i] && states[i]()
}
return this
},
}
return {
change: Action.changestate,
goes: Action.goes,
}
}

测试

1
2
3
4
5
6
7
var marry = new Marrystate()
marry
.change('jump', 'shoot')
.goes() // 触发一次动作: 跳跃 射击
.goes() // 触发一次动作: 跳跃 射击
.change('shoot')
.goes() // 触发一次动作: 射击