二、策略模式

策略类环境类组成。

  • 策略类

    封装了具体的算法,负责具体的计算过程

  • 环境类Context

    接受客户的请求,将请求委托给策略类

基于类的策略模式

Java like code

// 策略类
var PerformanceS = function () {};
PerformanceS.prototype.calculate = function (salary) {
  return salary * 3;
};
​
PerformanceA = function () {};
PerformanceA.prototype.calculate = function (salary) {
  return salary * 2;
};
​
PerformanceB = function () {};
PerformanceB.prototype.calculate = function (salary) {
  return salary * 1;
};
​
// 环境类
var Bonus = function () {};
Bonus.prototype.setPerformance = function (performance) {
  this.performance = performance;
};
Bonus.prototype.setSalary = function (salary) {
  this.salary = salary;
};
Bonus.prototype.calculateBonus = function () {
  return this.performance.calculate(this.salary);
};
​
var bonus = new Bonus();
bonus.setPerformance(new PerformanceS());
bonus.setSalary(1000);
console.log(bonus.calculateBonus()); // 3000
​
bonus.setPerformance(new PerformanceB());
console.log(bonus.calculateBonus()); // 1000

JavaScript的策略模式

js code

var performance = {
  S: function (salary) {
    return salary * 3;
  },
  A: function (salary) {
    return salary * 2;
  },
  B: function (salary) {
    return salary * 1;
  }
};
​
var getBonus = function (level, salary) {
  return performance[level](salary);
};
​
console.log(getBonus('S', 1000));  // 3000
console.log(getBonus('B', 1000));  // 1000

表单验证案例

<form id="regist" action="">
  <label for="username">
    用户名
    <input type="text" id="username" placeholder="请输入用户名" />
  </label>
  <label for="password">
    密码
    <input type="password" id="password" placeholder="请输入密码" />
  </label>
  <label for="tel">
    手机号
    <input type="text" id="tel" placeholder="请输入手机号" />
  </label>
  <button type="submit">注册</button>
</form>
var telReg = /^1[3|5|7|8|9][0-9]{9}$/;
​
var strategies = {
  isEmpty: function (value, errMsg) {
    if (value === '') return errMsg;
  },
  minLength: function (value, length, errMsg) {
    console.log('min');
    if (value.length < length) return errMsg;
  },
  isMobile: function (value, errMsg) {
    if (!telReg.test(value)) return errMsg;
  }
};
​
var Validator = function () {
  this.cache = [];
};
// add(form.input,minLength:6,不能少于6位数)
Validator.prototype.add = function (dom, rules) {
  for (var i = 0, rule; (rule = rules[i++]); ) {
    var self = this;
    (function (rule) {
      var args = rule.strategy.split(':');
      var errMsg = rule.errMsg;
​
      self.cache.push(function () {
        var strategy = args.shift();
        args.unshift(dom.value);
        args.push(errMsg);
        return strategies[strategy].apply(dom, args);
      });
    })(rule);
  }
};
​
Validator.prototype.start = function () {
  for (var i = 0, fn; (fn = this.cache[i++]); ) {
    var errMsg = fn();
    console.log(errMsg);
    if (errMsg) {
      return errMsg;
    }
  }
};
​
var form = document.getElementById('regist');
​
var validatFn = function () {
  var validator = new Validator();
  validator.add(form.username, [{ strategy: 'isEmpty', errMsg: '用户名不能为空' }]);
  validator.add(form.password, [
    { strategy: 'minLength:6', errMsg: '密码不能少于6位数' },
    { strategy: 'isEmpty', errMsg: '密码不能为空' }
  ]);
  validator.add(form.tel, [{ strategy: 'isMobile', errMsg: '手机号格式错误' }]);
​
  return validator.start();
};
​
form.onsubmit = function () {
  var ret = validatFn();
  if (ret) {
    alert(ret);
    return;
  }
};

总结

  • ❏ 策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重条件选择语句。
  • ❏ 策略模式提供了对开放—封闭原则的完美支持,将算法封装在独立的strategy中,使得它们易于切换,易于理解,易于扩展。
  • ❏ 策略模式中的算法也可以复用在系统的其他地方,从而避免许多重复的复制粘贴工作。
  • ❏ 在策略模式中利用组合和委托来让Context拥有执行算法的能力,这也是继承的一种更轻便的替代方案。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值