介绍
策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来。
一个基于策略模式的程序至少由两部分构成,第一个部分是一组策略类,包含了具体的算法实现;第二个部分是环境类,它可以接收客户的请求,随后把请求委托给指定的策略类,所以,环境类中一定要维持对策略类的引用。
JavaScript策略模式实现
JavaScript 中策略类可以用一个包裹各种算法实现的对象来实现,环境类则用函数来实现,代码如下:
// 策略对象(类)var strategies = {'S': function(salary) {return salary * 4;},'A': function(salary) {return salary * 3;},'B': function(salary) {return salary * 2;}};// 环境函数(类)var calculateBonus = function(level, salary) {return strategies[level](salary);}console.log(calculateBonus('S', 20000)); // 输出: 80000console.log(calculateBonus('A', 10000)); // 输出: 30000
策略模式的应用——表单校验
在实际开发中,我们通常会把算法的含义扩散开来,使策略模式也可以用来封装一系列的”业务规则”,只要这些业务规则指向的目标一致,并且可以被替换,我们就可以用策略模式来封装它们。
一个广泛使用策略模式的场景就是表单校验,通常有以下几条校验规则:
- 输入内容不能为空;
- 输入字符个数不能少于指定个数;
- 诸如手机号等的格式校验。
最终实现代码如下:
DOM 结构:
<!-- 其余代码省略 --><form action="/" method="POST"><input id="phoneEl" name="phone" type="text" placeholder="默认内容" /><input id="submitBtn" type="submit" value="提交" /></form>
JavaScript 代码:
// 策略对象(类)var strategies = {ifNonEmpty: function(value) {return value != '';},ifComplete: function(value, length) {return value.length == length;},ifMobile: function(value) {return /(^1[3|5|8][0-9]{9}$)/.test(value);}};// 环境函数(类)var bindStrategy = function(el, paramString) {var paramArray = paramString.split(':');var rule = paramArray[0];var params = paramArray.slice(1);params.unshift(el.value);return strategies[rule].apply(this, params);}var submitBtn = document.getElementById('submitBtn');var phoneField = document.getElementById('phoneEl');submitBtn.onclick = function() {// 绑定策略var ifNonEmpty = bindStrategy(phoneField, 'ifNonEmpty');var ifComplete = bindStrategy(phoneField, 'ifComplete:11');var ifMobile = bindStrategy(phoneField, 'ifMobile');console.log('ifNonEmpty: ' + ifNonEmpty,'ifComplete: ' + ifComplete,'ifMobile: ' + ifMobile);}
