什么是重复的 switch
重复的 switch 指同一组类型分支在多个地方重复出现:新增一种类型要改所有分支,漏一处就在某条路径上出错。处方是用以多态取代条件表达式把分支收敛到类型体系,或先用提取函数把散落的分支集中到一处;如果分支少而稳定,集中在单处的判断未必比多态更差。
基本信息
| 典型信号 | 同一枚举在多处分支判断,新增类型容易漏改 |
|---|---|
| 处方 | 以多态取代条件表达式、提取函数 |
| 权衡 | 分支少且稳定时,集中的判断未必更差 |
| 相邻问题 | 发散式变化、霰弹式修改 |
| 前提 | 类型体系能承载每种分支的行为 |
典型使用场景
- 订单类型在计价、校验、通知三处各有分支判断
- 日志级别判断散落在多个模块,规则调整要全局搜索
- 协议版本分支写在解析与序列化两处,容易不一致
- 权限类型在过滤与展示里各判断一次
- 导出格式分支出现在内容生成与文件命名两处
多态化方向
多态化方向
// 把分支收敛到类型体系
interface Shipping {
Money cost(Order order);
}
class Air implements Shipping { ... }
class Ground implements Shipping { ... }
// 调用方不再判断类型:order.shipping().cost(order)
// 新增类型只需加一个实现类处理方式选择
| 情况 | 建议 | 理由 |
|---|---|---|
| 分支在多处重复且会扩展 | 多态或集中一处 | 新增类型只改一个地方 |
| 只有一处判断且分支稳定 | 保留现状 | 多态引入的间接层未必划算 |
| 各分支逻辑差异很大 | 策略对象 | 避免子类里出现互不相干的代码 |
迁移中最容易出错的是默认分支:多态化后原来的兜底语义往往没有对应实现,行为在边角情况下悄然改变。迁移前把默认分支的行为写成用例。
不要为两个分支就搭起类层次:抽象成本高于收益时,把判断集中到一个函数里是更经济的选择。