js 设计模式之策略模式
// 策略模式 var validataRules = { 'minLeng' :function(val, length, msg) { if (val && val.length > 6) { return msg } }, 'isMobile': function(val, msg){ if (!/(^1[3|5|8][0-9]{9}$)/.test(val)){ return msg } }, 'isCardId': function(val, msg){ if (!/(^[1-9][1-9]{17}$)/.test(val)){ return msg } }, isNonEmpty: function (val, msg) { if (val === '') { return msg; } } } var validata = function () { this.item = [] } validata.prototype = { construcor: validata, add:function(val, rules) { var self = this; for(let i=0; i< rules.length; i++){ self.item.push(function(){ var argArr = rules[i].valiName.split(':'); var ruleName = argArr.shift() argArr.unshift(val) argArr.push(rules[i].msg) return validataRules[ruleName].apply(self, argArr) }) } }, start:function(){ for ( let i=0;i<this.item.length;i++){ var msg = this.item[i]() if (msg){ return msg } } } } $('#btn3').click(function() { var validataFunc = new validata() validataFunc.add('123',[{ valiName:'isMobile', msg:'请输入正确手机号' },{ valiName:'isNonEmpty', msg:'请输入内容' }]) var errMsg = validataFunc.start() if (errMsg){ console.log(errMsg) } }); })
1. 定义
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
2. 核心
将算法的使用和算法的实现分离开来。
一个基于策略模式的程序至少由两部分组成:
第一个部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。
第二个部分是环境类Context,Context接受客户的请求,随后把请求委托给某一个策略类。要做到这点,说明Context 中要维持对某个策略对象的引用
3. 实现
策略模式可以用于组合一系列算法,也可用于组合一系列业务规则
假设需要通过成绩等级来计算学生的最终得分,每个成绩等级有对应的加权值。我们可以利用对象字面量的形式直接定义这个组策略
4. 优缺点
优点
可以有效地避免多重条件语句,将一系列方法封装起来也更直观,利于维护
缺点
往往策略集会比较多,我们需要事先就了解定义好所有的情况