策略模式是指定义一系列算法并把它们封装起来。
比如我们在写一个注册页面,有以下几条校验逻辑
1.用户名不能为空
2.密码长度不能少于6位
通常我们会写成下面这个样子
function strategy(value) {
if(value === '') {
alert('用户名不能为空')
return false;
}
if(value.length < 6) {
alert('密码长度不能少于6位')
return false
}
}
这是一种很常见的编写方式,但是函数strategy缺乏弹性,如果我们在增加一条判断规则,则需要深入strategy函数内部去进行修改,这样就违反了开放-封闭原则。
我们将使用策略模式来重构上面代码
var strategyFuc = function () {
var strategy = {
isEmpty: function (value) {
if (value === '') {
alert('用户名不能为空')
return false;
}
},
minLength: function (value) {
if (value.length < 6) {
alert('密码长度不能少于6位')
return false
}
}
}
}
当然我们还需要继续完善上面的代码,增加一个校验策略接口和添加策略的接口
var strategyFuc = function () {
var strategy = {
isEmpty: function (value) {
if (value === '') {
alert('用户名不能为空')
return false;
}
},
minLength: function (value) {
if (value.length < 6) {
alert('密码长度不能少于6位')
return false
}
}
}
return {
// 校验策略
check: function (type, value) {
return strategy[type] ? strategy[type](value.trim()) : '没有该策略'
},
// 添加策略
add: function (type, fn) {
strategy[type] = fn
}
}
}()
// 判断是否是手机号码
function isPhone(value) {
if (!(/^1[3|5|8][0-9]{9}$/.test(value))) {
alert('手机号码错误')
return false
}
}
strategyFuc.check('isEmpty', '') // 用户名不能为空
strategyFuc.add('isPhone', isPhone('11111')) // 手机号码错误
策略模式使得算法脱离于逻辑而独立管理,可以让我们专心研发算法,而不必受模块逻辑所约束。