# 设计模式:策略模式
# 什么是策略模式
定义一系列算法,把他们一个个封装起来,并且可以相互替换。
# 使用场景
比如表单验证这个场景就非常合适,每一个验证规则都是一个算法。比如邮箱验证,字符串长短验证。 我们可以定义一套算法函数,然后针对每个字段的应用场景来调用甚至组合调用。
还有 css动画的运动曲线 ease ease-in ease-in-out 每种运动曲线都可以随意替换,这就是典型的策略模式。
# Coding
if 条件分支写法
- 用户名不能为空。
- 密码长度不能少于 6 位。
- 手机号码必须符合格式。
// 提交代码函数
fromDom.onsubmit = function() {
// 用户名验证
if (fromDom.username.value === '') {
alert('用户名不能为空');
return false;
}
if (fromDom.username.value.length > 8) {
alert('用户长度必须大于8位');
return false;
}
// 密码验证
if (fromDom.password.value.length > 8) {
alert('密码长度必须大于8位');
return false;
}
// 手机号码验证
if (!/(^1[3|5|8][0-9]{9}$)/.test(fromDom.phone.value)) {
alert('请输入有效的手机号码');
return false;
}
alert('验证通过');
}
策略模式写法
// 策略对象
const strategies = {
isNonEmpty: function(val, errMsg) {
if (val === '') {
return errMsg;
}
},
minLength: function(val, errMsg, length,) {
if (val.length < length) {
return errMsg;
}
},
isMobile: function(val, errMsg) {
var res = !/(^1[3|5|8][0-9]{9}$)/.test(val)
if (res) {
return errMsg;
}
}
}
// 校验对象
var Validateor = function() {
this.cache = [];
}
Validateor.prototype.add = function(value, rules) {
var self = this;
for (var i = 0, rule; rule = rules[i++];) {
;(function(rule) {
console.log(
rule
)
self.cache.push(function() {
return strategies[rule.action](value, rule.errMsg, rule.length)
})
})(rule);
}
}
Validateor.prototype.start = function() {
for (var i = 0, validateorFn; validateorFn = this.cache[i++];) {
var errMsg = validateorFn();
if (errMsg) {
return errMsg;
}
}
}
var fromDom = document.getElementById('form')
var validateorFn = function() {
var validateor = new Validateor();
validateor.add(fromDom.username.value, [
{
action: 'isNonEmpty',
errMsg: '用户名不能为空'
},
{
action: 'minLength',
length: 8,
errMsg: '用户名长度不能少于8位'
}
])
validateor.add(fromDom.password.value, [
{
action: 'minLength',
length: 8,
errMsg: '密码长度不能少于8位'
}
])
validateor.add(fromDom.phone.value,[
{
action: 'isMobile',
errMsg: '请输入正确的手机号码'
}
])
let errMsg = validateor.start();
return errMsg;
}
// 提交代码函数
fromDom.onsubmit = function() {
var errMsg = validateorFn();
if (errMsg) {
alert(errMsg);
}
alert('验证通过')
}
通过使用策略模式重构代码,我们消除了原程序中大片的条件分支语句。并且这样的代码可以很方便的实现功能扩展。
# 总结
- 策略模式是利用组合,委托,多态的思想。有效的避免了多重条件分支语句。
- 利于扩展,在 strategies 对象中可以任意新增功能。调用相应的算法时只需给定相应的配置即可。