1

策略模式

根据不同参数可以命中不同的策略

const strategy = {
  'S': function(salary) {
    return salary * 4
  },
  'A': function(salary) {
    return salary * 3
  },
  'B': function(salary) {
    return salary * 2
  }
}

const calculateBonus = function(level, salary) {
  return strategy[level](salary)
}

calculateBonus('A', 10000) // 30000

在函数是一等公民的 JS 中, 策略模式的使用常常隐藏在高阶函数中, 稍微变换下上述 demo 的形式如下, 可以发现我们平时已经在使用它了, 恭喜我们又掌握了一种设计模式。

  return salary * 4
}

const A = function(salary) {
  return salary * 3
}

const B = function(salary) {
  return salary * 2
}

const calculateBonus = function(func, salary) {
  return func(salary)
}

calculateBonus(A, 10000) // 30000

在一个Web项目中,注册,登录,修改用户信息,下订单等功能的实现都离不开提交表单.
假设我们正在编写一个注册的页面,在点击注册按钮之前,有如下几条校验逻辑。

所有选项不能为空

用户名长度不能少于6位

密码长度不能少于6位

手机号码必须符合格式

邮箱地址必须符合格式
HTML代码:

<body>
    <form action="http://www.baidu/register" id="registerForm" method="post" onsubmit=" return check()">
          <div class="form-group">
              <label for="user">请输入用户名:</label>
              <input type="text" class="form-control" id="user" name="userName">
          </div>
            <div class="form-group">
                <label for="pwd">请输入密码:</label>
                <input type="password" class="form-control" id="pwd" name="passWord">
            </div>
              <div class="form-group">
                  <label for="phone">请输入手机号码:</label>
                  <input type="tel" class="form-control" id="phone" name="phoneNumber">
              </div>
                <div class="form-group">
                    <label for="email">请输入邮箱:</label>
                    <input type="text" class="form-control" id="email" name="emailAddress">
                </div>
                <input type="submit" id="submit" value="提交">
    </form>
</body>

一般情况下的JavaScript代码:

<script>
  let registerForm = document.querySelector('#registerForm')
  function check(){
      if(registerForm.userName.value === ''){
          alert('用户名不能为空!')
          return false
      }
      if(registerForm.userName.value.length<6){
          alert('用户名长度不能少于6位!')
          return false
      }
      if(registerForm.passWord.value===''){
          alert('密码不能为空!')
          return false
      }
      if(registerForm.passWord.value.length<6){
          alert('密码长度不能少于6位!')
          return false
      }
      if(registerForm.phoneNumber.value===''){
      alert('手机号码不能为空!')
      return false
      }
     if(!/^1(3|5|7|8|9)[0-9]{9}$/.test(registerForm.phoneNumber.value)){
         alert('手机号码格式不正确')
         return false
     }
     if(registerForm.emailAddress.value===''){
     alert('邮箱地址不能为空!')
     return false
     }
     if(!/^\w+([+-.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(registerForm.emailAddress.value)){
         alert('邮箱地址格式不对')
         return false
     }
  }
</script>

策略模式

使用

// 获取表单form元素
var form = document.getElementById('f1');

// 创建表单校验实例
var validation = new Formvalidation(VerifiPolicy);
// 编写校验配置
validation.add(form.username, 'isNoEmpty', '用户名不能为空');
validation.add(form.password, 'minLength: 6', '密码长度不能小于6个字符');
validation.add(form.code, 'isMobile', '请填写正确的手机号');

// 开始校验,并接收错误信息
var errorMsg = validation.start();

// 如果有错误信息输出,说明校验未通过
if(errorMsg){
    // 做一些其他的事
    return false;
}

编写环境类


// 构造函数
var Formvalidation = function(VerifiPolicy){
    // 保存策略对象
    this.strategies = VerifiPolicy;
    // 验证缓存
    this.validationFns = [];
}

// add 方法  add方法第一个参数,是要验证的表单元素,第二个参数是一个字符串,使用 冒号(:) //分割,前面是策略方法名称,后面是传给这个方法的参数,第三个参数仍然是错误信息,
Formvalidation.prototype.add = function(dom, rule, errorMsg){

    var ary = rule.split(':');
    var arg = [];
    var self = this;
    this.validationFns.push(function(){
        arg = [];    // 重置参数
        var ruleName = ary[0];    // 策略对象方法名

        // 组装参数
        arg.push(dom.value);
        if(ary[1]){
            arg.push(ary[1]);
        }
        arg.push(errorMsg);

        // 调用策略函数
        return self.strategies[ruleName].apply(dom, arg);
    });
}

// 开始验证
Formvalidation.prototype.start = function(){
    for(var i = 0; ; i++){
        var msg = this.validationFns[i]();
        if(msg){
            return msg;
        }
    }
}

编写策略类

// 策略对象
var VerifiPolicy = {
    // 判断是否为空
    isNoEmpty : function(value, errorMsg){
        if(value == ''){
            return errorMsg;
        }
    },
    // 判断最小长度
    minLength : function(value, length, errorMsg){
        if(value.length < length){
            return errorMsg;
        }
    },
    // 判断是否为手机号
    isMobile : function(value, errorMsg){
        if(!/(^1[3|5|8][0-9]{9}$)/.test(value)){
            return errorMsg;
        }
    }
    // 其他
}

HappyCodingTop
526 声望847 粉丝

Talk is cheap, show the code!!