定义
定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换
优缺点
优点
- 策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重选择语句
- 策略模式提供了对开放-封闭原则的完美支持,将算法封装在独立的
strategy中,使得他们易于切换、易于理解、易于扩展 - 策略模式中的算法也可以复用在系统的其他地方,可以避免许多重复的复制粘贴工作
缺点
- 策略模式会在程序中增加许多策略类或者对象
- 要使用策略模式,必须了解所有的
strategy,必须了解各个strategy的不同点,这样才能选择一个合适的strategy
应用场景
不同场景使用不同算法需要动态切换算法
多重条件判断可以使用
实现
策略模式有很多经典使用场景这里以表单验证为例
// 定义算法/策略
const strategies = {
isNonEmpty: function (value, message) {
if (!value) {
return message
}
},
minLength: function (value, min, message){
if (value && value.length < min){
return message
}
},
isMobile: function(value, message){
if (value && !/^1\d{10}$/.test(value)) {
return message
}
}
};
// 定义Context
class Validator {
constructor() {
// 存放规则
this.rules = [];
}
// 添加规则
addRule(value, rule, message) {
function validate(){
// 将规则和参数分开
const arr = rule.split(':')
const strategy = arr.shift();
arr.unshift(value)
arr.push(message)
return strategies[strategy].apply(null, arr)
}
this.rules.push(validate)
}
// 校验
validate() {
const result = []
for (let i = 0; i < this.rules.length; i++) {
const rule = this.rules[i]
const message = rule();
if (message) {
result.push({index: i, message})
} else {
result.push({index: i, message: '验证通过'})
}
}
return result
}
}
// 测试
const validator = new Validator();
validator.addRule('', 'isNonEmpty', '该字段不能为空')
validator.addRule('23133', "isMobile", '手机号格式不正确')
validator.addRule('abc123', 'minLength:8', '密码长度不能小于8位')
validator.addRule('13666666666', 'isMobile', '手机号格式不正确')
const result = validator.validate()
for (let res of result) {
console.log(`规则${res.index + 1}-${res.message}`)
}
上面的例子中,通过定义一系列策略/算法, 然后在Context中管理使用,可以有效的避免多重条件判断,即使后面再增加多种规则只需要在策略中增加对应的算法,然后在添加一条规则就可以了。
参考文献
《Javascript设计模式与开发实践》