# JS设计模式-策略模式
策略模式:定义一系列的算法,把他们一个个封装起来,并让它们可以相互替换。
# 场景
策略模式的应用场景有许多,比如:网吧会员的计算系统,还有电商的优惠方式等等。在这里,我就用公司旁边那家网吧的计费方式为事例进行解析。
网吧的计费规则是这样的:(网费为5块一小时)
- 普通VIP,8折优惠
- 白银VIP,6折优惠
- 白银VIP,5折优惠
# 实现
我们很容易写下如下代码:
function calcPrice(level, price) {
if(level === 'VIP') {
return price * 0.8
}
if(level === 'silverVIP') {
return price * 0.6
}
if(level === 'goldVIP') {
return price * 0.5
}
return price
}
calcPrice('VIP', 50) // 返回 40
calcPrice('silverVIP', 50) // 返回 30
我们来看一下上面的代码,总结一下有以下几个缺点:
- if判断太多,影响函数的执行效率。(在这个函数,效率影响的可能没有那么明显)
- 如果我们再添加一种会员机制,比如:超级会员打4折。我们需要到calcPrice函数内部去修改,这个违反了开放-封闭原则
# 改进
对于第一个缺点,我们可以使用switch case这个语法糖进行改写一下,得到如下代码:
function calcPrice(level, price) {
switch (level) {
case 'VIP':
return price * 0.8
case 'silverVIP':
return price * 0.6
case 'goldVIP':
return price * 0.5
default:
return price
}
}
对于第二个缺点,我们就需要今天的主角,策略模式去修改了
# 写法一
var strategies = {
'VIP': function (price) {
return price * 0.8
},
'silverVIP': function (price) {
return price * 0.6
},
'goldVIP': function (price) {
return price * 0.5
},
}
function calcPrice(level, price) {
return strategies[level](price)
}
console.log(calcPrice('VIP', 50)) // 40
# 写法二
我们注意到上面代码,将所有的策略封装到一个对象中,也可以直接写成函数的形式。
function nVip(price) {
return price * 0.8
}
function silverVIP(price) {
return price * 0.6
}
function goldVIP(price) {
return price * 0.5
}
function calcPrice(fn, price) {
return fn(price)
}
console.log(calcPrice(nVip, 50))
注意方法二里面的VIP函数我加了一个小写的n变成nVip 主要原因是因为,函数类名需要大写。这点大家注意一下!
我个人比较偏爱方法一的实现,因为方法二产生了大量的函数名。浪费命名空间。
# 总结
- 策略模式能有有效避免多重判断,提升效率
- 做到了开放-封闭原则,由于策略定义在函数外面,易于扩展 切换和阅读
- 策略模式需要使用者知道很多,才能做好决策。这是一个小小的遗憾
# 拓展
其实,我们在表单验证的时候,会使用到大量的校验规则,我们这策略模式能够很好的管理起校验规则。有兴趣的同学可以去实现一下:
- 用户名不能为空,大于6个字符小于10个字符
- 密码长度大于6
- 手机号验证
我稍后会把,实现的代码放到我的官网,有兴趣的同学可以自取。
点击阅读原文 就可以访问我的小站了。
下一讲:我们一起来学习 单例模式!
关注公众号
组队学习,一同成长 
扫码添加好友
备注 加群学习 