一、代码坏味道分类与识别
1. 可维护性坏味道
识别特征:
- 硬编码:代码中出现魔数(magic number)、固定路径、固定ID
- 重复代码:相似代码段出现3次以上
- 过长方法:方法超过50行或需要滚动查看
- 过大类:类超过500行或包含10+个方法
- 深层嵌套:if/for嵌套超过3层
2. 可扩展性坏味道
识别特征:
- switch/case泛滥:同一文件中超过3个switch语句
-
条件逻辑复杂:if条件包含多个逻辑运算符(&&/ ) - 紧耦合:类直接引用具体实现而非接口
- 缺乏抽象:相似功能没有统一接口
3. 健壮性坏味道
识别特征:
- 空引用风险:未检查null直接访问成员
- 资源泄漏:未实现IDisposable或未使用using
- 异常处理不当:catch(Exception)或空catch块
- 并发问题:未使用lock/async的共享资源访问
二、优化策略与重构技巧
1. 针对可维护性的优化
硬编码优化:
// 坏代码
if (type == 1) PlaySound(1001);
// 优化后
[Serializable]
public class SoundConfig {
public SoundType type;
public int soundID;
}
public void PlaySound(SoundType type) {
var config = configs.First(c => c.type == type);
audioSource.Play(config.soundID);
}
重复代码优化:
// 提取公共方法
private void ShowError(string message) {
Debug.LogError(message);
UI.Toast.Show(message);
}
// 替代多处重复的
Debug.LogError("Config missing");
UI.Toast.Show("Config missing");
2. 针对可扩展性的优化
switch/case重构:
// 坏代码
switch (effectType) {
case EffectType.Fire: PlayFire(); break;
case EffectType.Ice: PlayIce(); break;
}
// 优化后(策略模式)
public interface IEffectPlayer {
void Play();
}
public class FireEffect : IEffectPlayer { ... }
public class IceEffect : IEffectPlayer { ... }
public class EffectSystem {
private Dictionary<EffectType, IEffectPlayer> players = new();
public void Play(EffectType type) {
players[type].Play();
}
}
条件逻辑简化:
// 坏代码
if (player.Health < 50 && !player.IsInvincible && enemy.IsAttacking) {
// ...
}
// 优化后
public bool PlayerIsVulnerable =>
Health < 50 && !IsInvincible;
if (enemy.IsAttacking && player.PlayerIsVulnerable) {
// ...
}
3. 针对健壮性的优化
空引用防护:
// 坏代码
var damage = target.GetComponent<Health>().CurrentHealth;
// 优化后
if (target.TryGetComponent<Health>(out var health)) {
var damage = health.CurrentHealth;
} else {
Debug.LogWarning("Target has no Health component");
}
三、识别坏代码的实用技巧
1. 代码扫描四步法
2. 气味检测清单
检测点 | 问题指标 | 优化方向 |
---|---|---|
方法参数 | >4个参数 | 封装参数对象 |
条件复杂度 | 条件含3+个逻辑运算符 | 提取布尔属性/方法 |
类型检查 | 频繁使用is/as | 引入多态设计 |
资源处理 | 缺少using/Dispose | 实现IDisposable模式 |
错误处理 | 空catch块或catch(Exception) | 特定异常处理 |
3. 量化评估指标
- 圈复杂度:>10的方法需要重构
圈复杂度 = 决策点数量 + 1
决策点:if, while, for, case, &&, ||
- 继承深度:>3层继承需考虑组合替代
- 耦合度:类直接依赖>5个其他类需解耦
四、持续改进的实践方法
1. 每日代码审查
- 15分钟规则:每天花15分钟审查一段代码
- 重点检查:昨天修改的代码是否有坏味道
- 记录成长:维护”重构日志”记录优化案例
2. 重构小技巧
3. 团队协作实践
- 坏味道看板:共享团队遇到的典型坏代码案例
- 重构Dojo:定期举办重构实战研讨会
- 代码卫生日:每月安排半天专门处理技术债务
五、学习路径建议
1. 基础阶段(1-3个月)
- 阅读《重构:改善既有代码的设计》
- 练习识别20种常见坏味道
- 掌握10种基本重构手法
2. 进阶阶段(3-6个月)
- 研究设计模式与重构的关系
- 实践测试驱动开发(TDD)
- 学习代码度量和静态分析工具
3. 精通阶段(6个月+)
- 参与开源项目重构
- 研究架构演进与重构策略
- 在团队中推广代码质量标准
识别坏代码的能力比编写新代码更重要。
优秀的开发者不是从不写坏代码,而是能快速识别并改进它。每次重构都是提升代码设计能力的机会!