设计模式-策略模式

92 阅读1分钟

定义

定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换

优缺点

优点

  1. 策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重选择语句
  2. 策略模式提供了对开放-封闭原则的完美支持,将算法封装在独立的strategy中,使得他们易于切换、易于理解、易于扩展
  3. 策略模式中的算法也可以复用在系统的其他地方,可以避免许多重复的复制粘贴工作

缺点

  1. 策略模式会在程序中增加许多策略类或者对象
  2. 要使用策略模式,必须了解所有的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设计模式与开发实践》