0%

策略模式

策略模式指的是定义一系列算法,把他们一个个封装起来,目的就是将算法的使用和算法的实现分离开来。stragey就是值为函数的变量,同时它还可以用来封装一系列的规则,比如常见的表单验证规则,只要这些规则指向的目标一致,并且可以被替换使用,那么就可以用策略模式来封装它们。

优点

  • 算法可以自由切换,避免了使用多层条件判断,增加了扩展性

缺点

  • 策略类增多,所有策略类都需要对外暴露。

例子

  • 写表单验证经常无止境的if…else写法,意识到这种写法不靠谱,于是我把检验规则放在一个对象中,在函数中对它进行控制,把规则与实现进行了分离,每次只需要在封装的规则中去修改配置。在后面的多种场景都用这种方法,解决了频繁使用if…else的问题,当第一次接触倒策略模式才知道这种写法也算策略模式。
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
const rules = {
cover_img: {
must: false,
msg: '请上传封面图片',
val: ''
},
name: {
must: true,
msg: '姓名不能为空',
val: ''
},
sex: {
must: true,
msg: '请填写性别',
val: ''
},
birthday: {
must: false,
msg: '请选择生日',
val: ''
},
}
function verify(){
for(const key in rules){
if(rules[key].must&&!rules[key].val){
console.log(rules[key].msg)
}
}
}
verify()

对于分支语句的优化,工厂方法模式,状态模式,策略模式。

表单验证例子:高阶函数

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<form action="http://xxx.com/register" id="registerForm" method="post">
请输入用户名:<input type="text" name="userName"></input>
输入密码:<input type="text" name="password">
输入手机号码:<input type="text" name="phoneNumber">
<button>提交</button>
</form>
<script>
//策略对象
let strategies = {
isNonEmpty:function(value,errorMsg){
if(value===''){
return errorMsg
}
},
minLength:function(value,length,errorMsg){
if(value.length<length){
return errorMsg
}
},
isMobile:function(value,errorMsg){
if(!/(^1[3][5][8][0-9]{9}$)/.test(value)){
return errorMsg
}
}
}
//客户调用代码
let registerForm = documetn.getElementById('registerForm')
let validatorFunc = function(){
let validator = new Validator()
validator.add(registerForm.userName,[{
strategy:'isNonEmpty',
errorMsg:'用户名不为空'
},{
strategy:'minLength:6',
errorMsg:'用户名长度不能小于10位'
}]);
validator.add(registerForm.password,[{
strategy:'minLength:6',
errorMsg:'用户长度不能小于10位'
}])
validator.add(registerForm.phoneNumber,[{
strategy:'isMobile',
errorMsg:'手机号码格式不正确'
}])
}
//验证类
Validator = function(){
this.cache=[];
}
Validator.prototype.add = function(dom,rules){
var self = this
for(let i=0,rule;rule = rules[i++];){
let self = this
(function(rule){
let strategyAry = rule.strategy.split(':')
let errorMsg = rule.errorMsg
self.cache.push(function(){
let strategy = strategyAry.shift()
strategyAry.unshift(dom.value)
strategyAry.push(errorMsg)
return strategies[strategy].apply(dom,strategyAry)
})
})(rule)
}
}
Validator.prototype.start = function(){
for(let i=0,validatorFunc;validatorFunc = this.caches[i++];){
let errorMsg = validatorFunc()
if(errorMsg){
return errorMsg
}
}
}
</script>

工厂方法模式:是一种创建型模式,最终目的是创建对象

状态模式和策略模式都是行为性模式,在状态模式中,核心是对状态的控制来决定表现行为,所以状态之间通常不能相互替代,否则将产生不同的行为结果。