重复的switch(Repeated Switches):坏味道识别与重构实战指南
重复的switch(Repeated Switches):坏味道识别与重构实战指南
24种代码坏味道系列 · 第12篇
1. 开篇场景
你是否遇到过这样的代码:相同的 switch 语句在多个地方重复出现,每次添加新的分支时,都需要在所有地方同步修改?
1 | double calculateDiscount(UserType type, double price) { |
这就是重复的switch的典型症状。相同的 switch 语句在多个地方重复出现,就像同一首歌的多个翻唱版本,当需要修改歌词时,必须同步更新所有版本。
当你需要添加新的用户类型时(如添加 PREMIUM_PLUS),你必须在所有使用 switch 的地方添加新的分支。这不仅浪费时间,更重要的是容易出错——漏掉一个地方,就会导致系统行为不一致。
2. 坏味道定义
重复的switch是指相同的 switch 语句在多个地方重复出现,应该使用多态替代。
就像同一份菜单的多个副本,当需要更新菜单时,必须同步更新所有副本,否则就会出现不一致。
核心问题:switch 语句通常表示类型相关的行为,应该使用多态来实现。多态可以让每个类型自己处理自己的行为,避免重复的 switch 语句。
3. 识别特征
🔍 代码表现:
- 特征1:相同的
switch语句在多个函数中重复出现 - 特征2:
switch语句根据类型执行不同的逻辑 - 特征3:添加新的类型时,需要在多个
switch中添加新分支 - 特征4:
switch语句的case数量较多(超过3个) - 特征5:
switch语句处理的是对象的行为,而不是简单的值映射
🎯 出现场景:
- 场景1:快速开发时,使用
switch处理类型相关的逻辑 - 场景2:从过程式编程迁移到面向对象时,没有重构
switch - 场景3:缺乏设计,没有考虑使用多态
- 场景4:重构不彻底,只修改了部分
switch语句
💡 快速自检:
- 问自己:这个
switch语句是否在其他地方也出现过? - 问自己:这个
switch语句是否可以根据类型使用多态替代? - 工具提示:使用代码分析工具检测重复的
switch语句
4. 危害分析
🚨 维护成本:添加新类型需要在多个 switch 中修改,时间成本增加2-3倍
⚠️ 缺陷风险:容易遗漏某些地方的修改,导致bug,风险增加70%
🧱 扩展障碍:添加新功能时不知道应该在哪里修改,容易产生新的重复
🤯 认知负担:需要记住所有使用 switch 的地方,增加了心理负担
5. 重构实战
步骤1:安全准备
- ✅ 确保有完整的单元测试覆盖
- ✅ 创建重构分支:
git checkout -b refactor/replace-switch-with-polymorphism - ✅ 使用版本控制,便于回滚
步骤2:逐步重构
重构前(问题代码)
1 | enum class UserType { |
问题分析:
- 相同的
switch逻辑在3个不同的方法中重复 - 如果添加新的用户类型,需要在3个地方添加新分支
- 如果修改某个用户类型的行为,需要在3个地方修改
重构后(清洁版本)
1 | // ✅ 使用多态替代 switch |
关键变化点:
用多态替代条件表达式(Replace Conditional with Polymorphism):
- 将
switch语句替换为多态 - 每个用户类型都有自己的实现
- 将
提高可扩展性:
- 添加新的用户类型只需创建新类
- 不需要修改现有代码
提高可维护性:
- 每个用户类型的行为集中在一个类中
- 修改某个用户类型的行为只需修改对应类
步骤3:重构技巧总结
使用的重构手法:
- 用多态替代条件表达式(Replace Conditional with Polymorphism):将
switch语句替换为多态 - 提取类(Extract Class):将类型相关的行为提取到类中
注意事项:
- ⚠️ 确保多态设计合理,不要过度设计
- ⚠️ 如果
switch语句很简单,可能不需要多态 - ⚠️ 重构后要更新所有使用处,确保行为一致
6. 预防策略
🛡️ 编码时:
即时检查:
switch语句是否在其他地方也出现过?switch语句是否可以根据类型使用多态替代?- 使用IDE的代码分析工具,检测重复的
switch语句
小步提交:
- 发现重复的
switch语句时,立即使用多态替代 - 使用”用多态替代条件表达式”重构,保持代码简洁
- 发现重复的
🔍 Code Review清单:
重点检查:
- 是否有重复的
switch语句? switch语句是否可以根据类型使用多态替代?- 添加新类型时是否需要在多个地方修改?
- 是否有重复的
拒绝标准:
- 相同的
switch语句在多个地方重复 switch语句处理的是对象的行为- 添加新类型需要在多个
switch中添加新分支
- 相同的
⚙️ 自动化防护:
IDE配置:
- 使用代码分析工具检测重复的
switch语句 - 启用
switch语句复杂度警告
- 使用代码分析工具检测重复的
CI/CD集成:
- 在CI流水线中集成代码分析工具
- 检测重复的
switch语句,生成警告报告
下一篇预告:循环语句(Loops)- 如何用STL算法替代命令式循环
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 青羽川!
评论
