JavaScript设计模式(二):策略模式

什么是策略模式

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

简单说就是对于不同的场景,我们才采取不同的方式来应对。举几个简单的小例子:

  1. 我们要组装一台电脑,如果预算充足的话,那就可以什么都用顶配,如果预算不够,那就追求性价比,用最少的预算获得最高的性能,如果基本没有什么预算,那就只能楼下网吧对付一下了,对于不同的预算就需要不同的策略。
  2. 在网购过程中,我们买的东西越多,相应的满减金额越多,能用的红包金额越大,省的钱越多。对于不同的金额,需要不同的计算策略。
  3. 年底计算绩效,不同的评分队对应不同的等级,需要不同的计算策略。

传统的策略模式

传统的策略模式一般分成两个部分,一个是接受调用,然后委托给某个策略来完成相应的功能,另一个部分就是把一系列的算法封装成一个个策略类。

举个例子

我们去某商场购物,如果拥有该商场的 vip 那么就能在总价的基础上进行打折,vip 分为 S 等级和 A 等级。

首先我们把不同的等级的计算策略封装起来,S 等级的 vip 可以打8折,A 等级的 vip 可以打九折。

1
2
3
4
5
6
7
8
9
10
11
const VipS = function () {};

VipS.prototype.discount = function (totalPrice) {
return totalPrice * 0.8;
}

const VipA = function () {};

VipA.prototype.discount = function (totalPrice) {
return totalPrice * 0.9;
}

然后再来写商品总价的类

1
2
3
4
5
6
7
8
9
10
11
12
13
const GoodsPrice = function () {};

GoodsPrice.prototype.setTotalPrice = function (totalPrice) {
this.totalPrice = totalPrice;
}

GoodsPrice.prototype.setCalculateMethod = function (obj) {
this.calculateMethod = obj.discount;
}

GoodsPrice.prototype.getActualAmount = function () {
return this.calculateMethod ? this.calculateMethod(this.totalPrice) : this.totalPrice;
}

通过 setTotalPrice 方法来设置原价的金额,通过 setCalculateMethod 方法来设置我们要执行的策略,最后通过 getActualAmount 来计算出应付金额。

1
2
3
4
const goods = new GoodsPrice();
goods.setTotalPrice(1000);
goods.setCalculateMethod(new VipS());
console.log(goods.getActualAmount()) // 800

由于我们的场景逻辑比较单一,所以使用策略模式反而看起来反而把问题搞复杂了,但如果在复杂的逻辑场景,例如我们在以上的场景下增加更多更细致的优惠方案策略,使用策略模式能让我们的代码逻辑更加清晰。

Javascript 的策略模式

在 Javascript 语言中,函数也是对象,我们可以把 n 个策略直接放到一个对象中。

1
2
3
4
5
6
7
8
const strategies = {
'vipS': function (totalPrice) {
return totalPrice * 0.8;
},
'vipA': function (totalPrice) {
return totalPrice * 0.9;
}
}
1
2
3
4
const calculateActualAmount = function( level, price ){
return level ? strategies[ level ]( price ) : price;
};
console.log( calculateActualAmount( 'vipS', 1000 ) );

小结

策略模式主要解决的就是很多相同的算法,我们一个个去使用 if…else… 去判断很麻烦,而且也不容易维护,代码可读性不高,所以我们把每个分支拆解成策略,避免使用多重判断。但还要注意的是如果策略过多的话,可能使用策略模式也并不那么合适,就需要考虑其他的设计模式来解决问题了。


JavaScript设计模式(二):策略模式
https://l1ushun.github.io/2023/10/10/design-strategy/
作者
shun
发布于
2023年10月10日