策略模式指的是定义一系列算法,把他们一个个封装起来,目的就是将算法的使用和算法的实现分离开来。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>
|
工厂方法模式:是一种创建型模式,最终目的是创建对象
状态模式和策略模式都是行为性模式,在状态模式中,核心是对状态的控制来决定表现行为,所以状态之间通常不能相互替代,否则将产生不同的行为结果。