JavaScript设计模式:策略模式

定义

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。
策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
简而言之,就是策略模式准备了一组算法,并将每个算法进行封装,使它们之间可用相互替换。 策略模式除了用来封装算法,也可以用来封装一系列的"业务规则",只要这些业务规则指向的目标一致,并且可以被替换使用,我们就可以用策略模式来封装它们。

例子:购物车结算时有多种折扣计算方式,满100-10,满200-25,8折,7折,这种逻辑我们可以用基本代码实现
function calcPrice(price, type) {
if (type === '100-10') {
price -= 10
} else if (type === '200-25') {
price -= 25
} else if (type === '80%') {
price *= 0.8
}
return price
}
const res = calcPrice(320, '100-10')

显而易见,这段代码虽然实现了我们想要的功能,但是很局限,有以下几种缺点:

  1. 一旦折扣种类修改,需要反复改源代码,违反了开放封闭原则
  2. 很容易陷入多重条件地狱,不断去累加判断条件
  3. 算法无复用性,在程序的其他地方需要重用,只能复制粘贴

相关概念

一个基于策略模式的程序至少由两部分组成。第一个部分是一组策略类,第二个部分是环境类Context。
  1. 策略类:策略类封装了具体的算法,并负责具体的计算过程。
  2. 环境类Context:环境类Context接受客户的请求,随后把请求委托给某一个策略类。

const calcPrice = (function () {
const sale = {
'100-10': function (price) { return price -= 10 },
'200-25': function (price) { return price -= 25 },
'80%': function (price) { return price *= 0.8 }
}
return function(price,type) {
// 判断对象里有没有这个折扣类型
if (!sale[type]) return '没有这个折扣'
return sale[type](price)
}
})()
console.log(calcPrice(320,'100-10'))
// 替换 Context 中当前保存的策略对象,便能执行不同的算法来得到我们想要的结果。

// 增加添加和删除折扣的接口
const calcPrice = (function () {
const sale = {
'100-10': function (price) {return price -= 10},
'200-25': function (price) {return price -= 25},
'80%': function (price) {return price *= 0.8}
}
function calcPrice(price, type) {
if (!sale[type]) return '没有这个折扣'
return saletype
}
calcPrice.add = function (type, fn) {
// 判断折扣是否存在
if (sale[type])
sale[type] = fn
return '添加成功'
}
// 删除折扣
calcPrice.del = function (type) {
delete sale[type]
}
return calcPrice
})()

// 添加折扣
calcPrice.add('70%', function (price) {return price *= 0.7})
// console.log(calcPrice(300,'70%'))

// 删除折扣
calcPrice.del('100-10')
// console.log(calcPrice(300,'100-10'))

策略模式的优缺点

从上述的例子中,很明显能总结出策略模式的优点

  1. 采用组合、委托和多态等技术和思想、有效避免了多重条件选择语句
  2. 采用了开放-封闭原则,将算法封装在独立的strategy中,易于理解、切换、拓展
  3. 策略模式中的算法可以进行复用,从而避免很多地方的复制粘贴

同时策略模式也有其缺点,但是并不影响我们对策略模式的使用

  1. 在策略模式中,我们会增加很多策略类、策略对象
  2. 要使用策略模式,我们必须了解到所有的strategy、必须了解各个strategy之间的不同点,才能选择一个适合的strategy。
上一篇:javaday01


下一篇:数据分析实战100例(基于SQL&Pandas)_探索Chipotle快餐数据