策略模式

128 阅读2分钟

策略模式的难度不大,但是掌握它却能培养良好的编程习惯,提升代码的清晰度。

电商促销活动

业务场景是这样的: 有一项商品,价格是固定的。每次搞活动时,优惠力度不一样,因此在购物车计算价格时,会根据不同的促销活动,计算不同的价格。

活动类型计算:

  • 6.18促销,商品打9折
  • 8.8促销,商品打8折
  • 11.11促销,商品先提价30%,然后再打7折

使用if-else实现

function calculate(type, price) {
	let result = 0;
	if(type==='6.18') {
    	result = price * 0.9;
    }
    if(type==='8.8') {
    	result = price * 0.8;
    }
    if(type==='11.11') {
    	result = price * 1.3 * 0.7;
    }
    return result;
}
// 调用
const result = calculate('11.11', 100);

使用if-else的缺陷

  • 违背“单一功能”原则。它将三个逻辑放在同一函数中,一旦价格计算的逻辑代码变得复杂,这个函数的内容立马就会变得膨胀。一个函数的内容越多,阅读起来越困难。
  • 违背“开放封闭”原则。假如有一天,我们加了一个圣诞活动,我们又得修改calculate函数的逻辑。虽然只增部分逻辑,但是却影响整体的逻辑,不得不对整个函数进行测试。

作为开发人员,你可能只会增加圣诞活动情况下的测试,但是在测试人员的眼里,由于你这段函数整合了所有活动的计算逻辑,他就需要在线上环境构造所有活动的条件,将所有的情况测试一遍,资源消耗极大。

重构拆分

//第一步,将三个逻辑拆分出来
function typeOf618 (price) {
	return price * 0.9
}
function typeOf818(price) {
	return price * 0.8
}
function typeOf1111(price) {
	return price * 1.8 * 0.7
}
//第二步,定义策略类
const caculateStrategy = {
	618: typeOf618,
    818: typeOf818,
    1111: typeOf1111
}
//第三步,调用计算
function caculate(type, price) {
	return caculateStrategy[type](price);
}

这个时候,增加一个新的圣诞活动,你就只需要增加新的函数,而不需要修改原函数的逻辑

caculateStrategy.1225 = function(price) { return price * 0.85 };

总结

策略模式使得新增功能不影响原功能的运行。代码的稳定性增加了,阅读起来容易了,每次新增活动,也只需要测试新增活动,是不是好处多多啊!