js 设计模式——策略模式
Posted loveyt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js 设计模式——策略模式相关的知识,希望对你有一定的参考价值。
策略模式(Strategy)
定义:将定义的一组算法封装起来,使其相互之间可以替换。封装的算法具有一定的独立性,不会随客户端的变化而变化
废话不多说,先来个例子
// 例如要写一个计算两个数加减乘除的方法,会有人这么写
countNum(type, num1, num2)
if(type === 'add')
return num1 + num2
else if(type === 'subtract')
return num1 - num2
else if(type === 'multiply')
return num1 * num2
else
return num1 / num2
countNum('add', 9, 3) // 12
countNum('subtract', 9, 3) // 6
countNum('multiply', 9, 3) // 27
countNum('', 9, 3) // 3
上面的例子,一定会有人这么写的,你要说没有我也没办法(~ ̄▽ ̄)~,这样写首先不利于维护,其实也不好方便扩展
改进一下:
let countNum =
add(num1, num2)
return num1 + num2
,
subtract(num1, num2)
return num1 - num2
,
multiply(num1, num2)
return num1 * num2
,
divide(num1, num2)
return num1 / num2
,
countNum.add(9, 3) // 12
countNum.subtract(9, 3) // 6
countNum.multiply(9, 3) // 27
countNum.divide(9, 3) // 3
上面的例子就可以看成是一个策略模式
now,现在有个需求,快要圣诞节,所以咧,超市中一部分商品8折出售,一部分9折出售,等到元旦还要搞大事,普通用户满100返30,VIP用户满100返50,用策略模式来实现
// 定义一个策略对象
let priceceStrategy = function()
// 内部算法对象
let strategy =
return30(price)
return price + parseInt(price / 100) * 30
,
return50(price)
return price + parseInt(price / 100) * 50
,
price80(price)
return price * 80 / 100
,
price90(price)
return price * 90 / 100
// 策略方法调用接口
return
strategyFunction(type, price)
return strategy[type] && strategy[type](price)
,
// 添加算法
addStrategy(type, fn)
strategy[type] = fn
()
priceceStrategy.strategyFunction('return30', 100) // 130
priceceStrategy.strategyFunction('return50', 100) // 150
priceceStrategy.strategyFunction('price80', 100) // 80
priceceStrategy.strategyFunction('price90', 100) // 90
// 添加一个算法
priceceStrategy.addStrategy('return70', (price) =>
return price + parseInt(price / 100) * 70
)
console.log(priceceStrategy.strategyFunction('return70', 100)) // 170
还有我们的表单验证也可以使用策略模式
// 定义一个策略对象
let inputStrategy = function()
// 内部算法对象
let strategy =
notNull(value)
return /\s+/.test(value) ? '请输入内容' : ''
,
number(value)
return /^[0-9]+(\.[0-9]+)?$/.test(value) ? '' : '请输入数字'
// 策略方法调用接口
return
check(type, value)
// 去除空白符
value = value.replace(/^\s+|\s+$/g, '')
return strategy[type] && strategy[type](value)
,
// 添加策略
addStrategy(type, fn)
strategy[type] = fn
()
// 添加算法
inputStrategy.addStrategy('nickName', (value) =>
return /^[a-zA-Z]\w3,7$/.test(value) ? '' : '请输入4-8为昵称'
)
总结
策略模式属于对象行为型模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响 到客户端的情况下发生变化。通常,策略模式适用于当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
策略模式中的三个对象:
- 环境对象:该类中实现了对抽象策略中定义的接口或者抽象类的引用。
- 抽象策略对象:它可由接口或抽象类来实现。
- 具体策略对象:它封装了实现同不功能的不同算法。
利用策略模式构建应用程序,可以根据用户配置等内容,选择不同有算法来实现应用程序的功能。具体的选择有环境对象来完成。采用这种方式可以避免由于使用条件语句而带来的代码混乱,提高应用程序的灵活性与条理性。
优点:
- 优化多重条件判断,采用策略模式是的算法更利于维护
- 可扩展性,策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
- 策略类之间可以自由切换,由于策略类都实现同一个接口,所以使它们之间可以自由切换。
缺点:
- 由于选择哪种算法的决定权在用户,所以对用户来说就必须了解每种算法的实现。
- 由于每种算法间相互独立,这样对于一些复杂的算法处理相同逻辑的部分无法实现共享,这就会造成一些资源的浪费。
以上是关于js 设计模式——策略模式的主要内容,如果未能解决你的问题,请参考以下文章