重构询价逻辑
使用策略模式重构多条件询价代码
问题
电商系统中,不同用户类型有不同的折扣策略:
- 普通用户:原价
- 会员用户:9 折
- VIP 用户:8 折
- 超级 VIP:7 折 + 满 100 减 20
原始代码使用大量 if-else,如何重构使其更易维护和扩展?
解答
原始代码(问题代码)
function getPrice(userType, price) {
if (userType === 'normal') {
return price
} else if (userType === 'member') {
return price * 0.9
} else if (userType === 'vip') {
return price * 0.8
} else if (userType === 'superVip') {
const discounted = price * 0.7
return discounted >= 100 ? discounted - 20 : discounted
}
return price
}
问题:每次新增用户类型都要修改函数,违反开闭原则。
策略模式重构
// 策略对象:每种用户类型对应一个计价函数
const priceStrategies = {
normal(price) {
return price
},
member(price) {
return price * 0.9
},
vip(price) {
return price * 0.8
},
superVip(price) {
const discounted = price * 0.7
return discounted >= 100 ? discounted - 20 : discounted
}
}
// 询价函数:根据用户类型调用对应策略
function getPrice(userType, price) {
const strategy = priceStrategies[userType]
return strategy ? strategy(price) : price
}
// 使用
console.log(getPrice('normal', 100)) // 100
console.log(getPrice('member', 100)) // 90
console.log(getPrice('vip', 100)) // 80
console.log(getPrice('superVip', 200)) // 120 (200 * 0.7 - 20)
支持动态扩展
// 创建可扩展的询价器
function createPricer(strategies = {}) {
return {
// 添加新策略
addStrategy(type, fn) {
strategies[type] = fn
return this
},
// 计算价格
getPrice(type, price) {
const strategy = strategies[type]
return strategy ? strategy(price) : price
}
}
}
// 使用
const pricer = createPricer()
.addStrategy('normal', price => price)
.addStrategy('member', price => price * 0.9)
.addStrategy('vip', price => price * 0.8)
// 后续新增策略,无需修改原有代码
pricer.addStrategy('newYear', price => price * 0.5)
console.log(pricer.getPrice('vip', 100)) // 80
console.log(pricer.getPrice('newYear', 100)) // 50
结合 Map 实现
// 使用 Map 存储策略,支持任意类型作为 key
const strategies = new Map([
['normal', price => price],
['member', price => price * 0.9],
['vip', price => price * 0.8]
])
function getPrice(userType, price) {
const strategy = strategies.get(userType)
return strategy ? strategy(price) : price
}
// 新增策略
strategies.set('superVip', price => {
const discounted = price * 0.7
return discounted >= 100 ? discounted - 20 : discounted
})
关键点
- 策略模式:将算法封装成独立函数,通过映射表查找调用
- 开闭原则:新增策略只需添加映射,无需修改主函数
- 消除 if-else:用对象/Map 的键值查找替代条件判断
- 单一职责:每个策略函数只负责一种计价逻辑
- 易于测试:每个策略可独立进行单元测试
目录