设计模式-策略模式

113 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

什么是策略模式

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

正所谓条条大陆通罗马,选择一个最适合当前的方式达到重点

  • 如果没有时间但是有钱,可以选择坐飞机。
  • 如果没有钱,可以选择坐大巴或者火车。
  • 如果再穷一点,可以选择骑自行车

实现一个策略模式

比如员工评级,不能档位发放不同的奖金,当我们遇到这种情况的时候就可以考虑使用策略模式了

const calculateBonus = function (performanceLevel, salary) {
  if (performanceLevel === 'S') {
    return salary * 4;
  }
  if (performanceLevel === 'A') {
    return salary * 3;
  }
  if (performanceLevel === 'B') {
    return salary * 2;
  }
};
calculateBonus('S', 200); // 800
calculateBonus('B', 100); // 200

改造一下上面的代码:

const strategies = {
  S: function (salary) {
    return salary * 4;
  },
  A: function (salary) {
    return salary * 3;
  },
  B: function (salary) {
    return salary * 2;
  },
};
const calculateBonus = function (level, salary) {
  return strategies[level](salary);
};

怎么样?改造完之后的代码是不是看上去顺眼多了。

javascript 中函数也是一个对象,因此把级别直接定义为一个对象,每个策略对象负责的算法已被各自封装在对象内部,当我们对这些策略对象发出“计算奖金”的请求时,它们会返回各自不同的计算结果,这正是对象多态性的体现,

总结

策略模式优点:

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

策略模式缺点:

  1. 使用策略模式会在程序中增加许多策略类或者策略对象,但实际上这比把它们负责的逻辑堆砌在 Context 中要好。
  2. 要使用策略模式,必须了解所有的 strategy,必须了解各个 strategy 之间的不同点,这样才能选择一个合适的 strategy。比如,我们要选择一种合适的旅游出行路线,必须先了解选 择飞机、火车、自行车等方案的细节。此时 strategy 要向客户暴露它的所有实现,这是违反最少知识原则的。

其他:一等函数对象与策略模式

在函数作为一等对象的语言中,策略模式是隐形的。strategy 就是值为函数的变量。

那我们就吧对象改写成函数吧。

var S = function (salary) {
  return salary * 4;
};
var A = function (salary) {
  return salary * 3;
};
var B = function (salary) {
  return salary * 2;
};
var calculateBonus = function (fn, salary) {
  return fn(salary);
};

calculateBonus(S, 10000); // 输出:40000