js策略模式
策略模式:定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化不会影响到使用算法的客户。
例子1:根据员工薪水salary、绩效等级S、A、B、C,来计算年终奖
|
//封装了所有算法的策略对象 var strategies = { 'S' : function (salary){ return salary*4; }, 'A' : function (salary){ return salary*3; }, 'B' : function (salary){ return salary*2; }, 'C' : function (salary){ return salary*1; } } //定义自动选择算法的方法 var calculateBonus = function (level,salary){ return strategies[level](salary); } //使用 calculateBonus( 'S' ,9000); //36000 calculateBonus( 'B' ,5000); //10000 |
例子2:表单验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
//定义验证算法的策略对象 var strategies = function (){ isEmpty: function (value,errorMsg){ if (value = '' ){ return errorMsg; } } outRangle: function (value,min,max,errorMsg){ if (value.length > max || value.length < min){ return errorMsg; } } isSame: function (oldValue,newValue,errorMsg){ if (newValue !== oldValue){ return errorMsg; } } isMobile: function (value,errorMsg){ if (!/(^1[3|5|8][0-9]{9}$)/.test(value)){ return errorMsg; } } ...... } |
也可不定义以下的Validator类,直接在触发失去焦点事件时调用strategies对象的属性方法来验证当前input项
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
|
//定义Validator var Validator = function (){ this .cache = []; } Validator.prototype.add = function (elem,rules){ var self = this ; for ( var i = 0, rule; rule = rules[i++]){ ( function (rule){ var strategyAry = rule.strategy.split( ':' ); var errorMsg = rule.errorMsg; self.cache.push( function (){ var strategy = strategyAry.shift(); strategyAry.unshift(elem.value); strategyAry.push(errorMsg); return strategies[strategy].apply(elem,strategyAry); }) })(rule) } } Validator.prototype.start = function (){ for ( var i = 0, func; func = this .cache[i++]){ var errorMsg = func(); if (errorMsg){ return errorMsg; } } } |
使用:
1
2
3
4
5
6
7
8
|
var validator = new Validator(); validator.add(elem.userName,[ {strategy: 'isEmpty' , errorMsg: '用户名不能为空' }, {strategy: 'outRangle:6:12' , errorMsg: '用户名长度为6-12位' } ]); ...... var errorMsg = validator.start(); ...... |
作用:
1.所有的这些算法都是做相同的事情,只是实现不同。
2.以相同的方式调用所有的方法,减少了各种算法与使用算法类之间的耦合。
3.单独定义算法类,也方便了单元测试。
注意事项:
1.不仅可以封装算法,也可以用来封装几乎任何类型的规则,是要在分析过程中需要在不同时间应用不同的业务规则,就可以考虑是要策略模式来处理各种变化