一、代码坏味道分类与识别

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个月+)

  • 参与开源项目重构
  • 研究架构演进与重构策略
  • 在团队中推广代码质量标准

识别坏代码的能力比编写新代码更重要。优秀的开发者不是从不写坏代码,而是能快速识别并改进它。每次重构都是提升代码设计能力的机会!