转载

设计模式 —— 策略模式

策略模式的定义:定义一系列的算法,把它们一个个封装起来,并且使他们可以相互替换。

使用策略模式计算奖金

最初的实现代码

我们编写一个函数来计算每个人的奖金数额,这个函数接收两个参数:员工的工资数额和他的绩效考核等级

const calulateBous = (performanceLevel, salary) => {
 switch(performanceLevel) {
 case 'S':
 return salary*4
 case 'A':
 return salary*3
 case 'B':
 return salary*2
 }
}

我们可以看到上面那段代码有几个缺点:

  1. 很多 case 语句,这些语句需要覆盖所有的逻辑分支
  2. calulateBous 函数缺乏弹性,如果需要增加一个新的绩效等级 C,那我们必须深入 calulateBous 函数内部去实现,这是违反 开放-封闭原则
  3. 算法的复用性差,如果在程序的其他地方需要复用这些计算奖金的算法,那就只能复制粘贴了

因此,我们需要重构这段代码

使用组合函数重构代码

const performanceS = (salary) => {
 return salary*4
}
const performanceA = (salary) => {
 return salary*3
}
const performanceB = (salary) => {
 return salary*2
}
const calulateBous = (performanceLevel, salary) => {
 switch(performanceLevel) {
 case 'S':
 return performanceS(salary)
 case 'A':
 return performanceA(salary)
 case 'B':
 return performanceB(salary)
 }
}

目前,我们的程序得到了一点的改善,但是这种改善非常有限,我们依然没有解决最重要的问题: calulateBous 函数有可能越来越庞大,并且在系统变化时缺乏弹性。

使用策略模式重构代码

const performanceS = function(){}
performanceS.prototype.calulate = salary => {
 return salary*4
}
const performanceA = function(){}
performanceA.prototype.calulate = salary => {
 return salary*3
}
const performanceB = function(){}
performanceB.prototype.calulate = salary => {
 return salary*3
}
const Bonus = function(){
 this.salary = null // 原始工资
 this.strategy = null // 绩效等级对应的策略对象
}
Bonus.prototype.setSalary = salary => {
 this.salary = salary
}
Bonus.prototype.setStrategy = strategy => {
 this.strategy = strategy
}
Bonus.prototype.getBonus = () => {
 return this.strategy.calulate(this.salary)
}
  • 定义一系列的算法,把它们各自封装成策略类,算法被封装在策略类内部的方法里面,在客户对 Context 发起请求的时候,Context 总是把请求委托给这些策略类、对象中间的某一个去处理。

JavaScript 版本的策略模式

在 JavaScript 中,函数也是对象,所以更简单和直接的方法就是将 strategy 直接定义为对象。

const strategies = {
 S(salary) {
 return salary*4
 },
 A(salary) {
 return salary*3
 }
 B(salary) {
 return salary*2
 }
}

同样的,Context 也没必要用 Bonus 来表示,我们依旧用 calculateBonus 来充当 Context 来接收用户的请求。

const calulateBous = (performanceLevel, salary) => {
 return strategies[performanceLevel](salary)
}
原文  http://mertensming.github.io/2017/01/28/js-graphic-design-patterns/
正文到此结束
Loading...