JavaScript-策略模式

策略模式

定义

定义一系列的算法,把他们封装成策略类,并使他们可以相互替换.
策略模式的目的就是把算法的使用和实现分离开来.
一个基于策略模式的至少由两部分组成.第一部分是一组策略类(可变),策略类封装了具体的算法,并负责具体的计算过程.第二个部分是环境类Context(不变),Context接受客户的请求,随后将请求委托给某一个策略类,要做到这一点,说明Context中要维持某个某个策略类的引用

基于类的策略模式

// 模拟策略类的接口
class Strategy {
  doOperation() {
    throw new Error("子类必须实现doOperation方法");
  }
}

// 策略类
// 拥有相同的接口doOperation,环境类中可以直接调用
class OperationAdd extends Strategy {
  doOperation(num1, num2) {
    return num1 + num2;
  }
}

class OperationSubstract extends Strategy {
  doOperation(num1, num2) {
    return num1 - num2;
  }
}

class OperationMultiply extends Strategy {
  doOperation(num1, num2) {
    return num1 * num2;
  }
}

// 环境类
// 持有策略类对象的引用
class Context {
  constructor(strategy) {
    this.strategy = strategy;
  }
  // 统一调用策略类对象的方法
  executeStrategy(num1, num2) {
    return this.strategy.doOperation(num1, num2);
  }
  // 更换策略类对象
  setStrategy(strategy) {
    this.strategy = strategy;
  }
}

const context = new Context(new OperationAdd());
const retAdd = context.executeStrategy(1, 1);
console.log("retAdd:>>>", retAdd); //2

context.setStrategy(new OperationSubstract());
const retSubstract = context.executeStrategy(10, 1);
console.log("retSubstract:>>>", retSubstract); //9

context.setStrategy(new OperationMultiply());
const retMultiply = context.executeStrategy(2, 2);
console.log("retMultiply:>>>", retMultiply); //4

javascript策略模式-表单验证

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>策略模式-校验表单</title>
  </head>
  <body>
    <form id="registerForm" method="post">
      用户名: <input type="text" name="username" /><br />
      密码:<input type="text" name="password" /><br />
      手机号码:<input type="text" name="phone" /><br />
      <button type="submit">提交</button>
    </form>
    <script>
      //策略类对象
      const strategies = {
        isNoEmpty(value, errMsg) {
          if (value == "") {
            return errMsg;
          }
        },
        isNoSpace(value, errMsg) {
          if (value.trim() == "") {
            return errMsg;
          }
        },
        minLength(value, length, errMsg) {
          if (value.trim().length < length) {
            return errMsg;
          }
        },
        maxLength(value, length, errMsg) {
          if (value.trim().length > length) {
            return errMsg;
          }
        },
        isMobile(value, errMsg) {
          if (
            !/^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|17[7]|18[0|1|2|3|5|6|7|8|9])\d{8}$/.test(
              value
            )
          ) {
            return errMsg;
          }
        },
      };

      // 验证类
      class Validator {
        constructor() {
          // 存储待执行的验证函数
          this.caches = [];
        }

        // 保存验证函数
        //dom:待验证的表单项,如input
        // rules:{strategy:string,errMsg:string}[]
        add(dom, rules) {
          let strategyArr, strategyName;
          for (let i = 0, rule; (rule = rules[i]); i++) {
            strategyArr = rule.strategy.split(":");
            strategyName = strategyArr.shift();
            strategyArr.unshift(dom.value);
            strategyArr.push(rule.errMsg);
            this.caches.push(() => {
            // 通过不同的策略名字来来调用不同的算法策略
              return strategies[strategyName].apply(dom, strategyArr);
            });
          }
        }

        start() {
          console.log(this.caches.length);
          let errMsg;
          for (let i = 0, fn; (fn = this.caches[i++]); ) {
            errMsg = fn();
            if (errMsg) {
              return errMsg;
            }
          }
        }
      }

      const form = document.querySelector("#registerForm");
      // 这里有bug,isNOEmpty没有显示
      form.onsubmit = function (e) {
        try {
          const ret = validateFunc();
          if (ret) {
            console.log(ret);
          }
        } catch (e) {
          console.log(e);
        }
        e.preventDefault();

        return false;
      };

      function validateFunc() {
        const validator = new Validator();
        validator.add(form.username, [
          { strategy: "isNoEmpty", errMsg: "用户名不能为空" },//通过strategy指定不同的算法
          { strategy: "minLength:6", errMsg: "用户名至少为6位" },
        ]);
        validator.add(form.password, [
          { strategy: "isNoSpace", errMsg: "密码不能为空" },
          { strategy: "minLength:6", errMsg: "密码至少为6位" },
        ]);
        validator.add(form.phone, [
          { strategy: "isNoSpace", errMsg: "手机号码不能为空" },
          { strategy: "isMobile", errMsg: "手机号码格式不对" },
        ]);
        return validator.start();
      }
    </script>
  </body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值