多条件分支用策略模式重构,核心是将各分支逻辑抽为独立函数并用对象映射或Context类统一管理;轻量场景用对象字面量映射,动态/有状态场景用Context封装;需支持校验、兜底、模块化加载。

多条件分支用策略模式重构,核心是把每个分支逻辑抽成独立函数,再用对象映射或类结构统一管理,彻底摆脱 if-else 堆叠。
用对象字面量做策略映射
这是最轻量、最常用的方式,适合业务规则相对稳定、策略函数无状态的场景。
- 把每种条件对应的处理逻辑写成单独函数,作为对象的属性值
- 键名就是策略标识(比如用户类型、绩效等级、支付方式)
- 调用时直接通过 key 查找并执行,无需逐条判断
例如折扣计算:
const discountStrategies = {VIP: (amount) => amount * 0.2,
SVIP: (amount) => amount > 100 ? amount * 0.5 + 20 : amount * 0.5,
NEW_USER: () => 10,
DOUBLE_11: (amount) => amount * 0.3
};
function calculateDiscount(userType, amount) {
const strategy = discountStrategies[userType];
return strategy ? amount - strategy(amount) : amount;
}
用 Context 类封装策略切换逻辑
当需要运行时动态更换策略、或策略本身有状态(比如带缓存、需初始化),推荐加一层 Context。
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- Context 持有一个 strategy 引用,提供 setStrategy 和 execute 方法
- 策略可以是函数,也可以是带方法的对象或类实例
- 便于在测试中 mock 策略,也方便扩展日志、兜底、超时等横切逻辑
例如支付方式切换:
class PaymentContext {constructor(strategy) {
this.strategy = strategy;
}
setStrategy(strategy) {
this.strategy = strategy;
}
pay(amount) {
return this.strategy.pay(amount);
}
}
const creditStrategy = { pay: (a) => console.log(`信用卡付 ${a}`) };
const alipayStrategy = { pay: (a) => console.log(`支付宝付 ${a}`) };
const ctx = new PaymentContext(creditStrategy);
ctx.pay(99); // 信用卡付 99
ctx.setStrategy(alipayStrategy);
ctx.pay(199); // 支付宝付 199
策略支持参数校验和兜底 fallback
真实项目中不能只靠 key 存在与否判断,要兼顾健壮性。
- 策略对象可自带 validate 方法,提前拦截非法输入
- 定义 default 策略或 throw 明确错误,避免静默失败
- 必要时加中间件式包装,比如统一记录策略命中日志
示例:
const strategies = {A: { validate: (s) => s > 0, exec: (s) => s * 4 },
B: { validate: (s) => s >= 1000, exec: (s) => s * 3 },
default: { exec: () => 0 }
};
function runStrategy(level, salary) {
const s = strategies[level] || strategies.default;
if (s.validate && !s.validate(salary)) {
throw new Error(`不满足 ${level} 级别要求`);
}
return s.exec(salary);
}
策略模块化与按需加载
大型应用中策略可能很多,全部加载影响首屏性能。
- 把策略拆成单独文件,按需 import 或动态 import()
- 用工厂函数生成策略对象,延迟初始化开销大的策略
- 结合 webpack 的 module federation 或微前端,让不同团队维护各自策略
比如促销策略分散在不同包里:
async function getPromoStrategy(type) {switch (type) {
case 'flash_sale': return (await import('./strategies/flash.js')).default;
case 'member_day': return (await import('./strategies/member.js')).default;
default: return defaultStrategy;
}
}

















