第一次接触代码重构这个概念时,我天真地以为这不过是把旧代码重新排列组合的体力劳动。直到在维护一个十万行级别的遗留系统时,我才真正理解Martin Fowler在《重构》中的那句话:"重构是在不改变代码外在行为的前提下,对代码内部结构进行改善的过程。"这哪里是简单的代码搬家,分明是一场精密的外科手术。
十年前接手的一个电商促销系统就是典型案例。表面上看功能一切正常,但每次新增促销规则都需要修改五六个分散的文件,团队成员平均每周要花3小时处理因修改引发的连锁bug。当我用两个月时间完成重构后,新增同类功能的平均时间缩短到15分钟,线上故障率下降92%。这不是靠机械地重写代码实现的,而是通过系统性地识别代码坏味道、设计更合理的抽象层、建立清晰的模块边界等技术决策达成的。
开始重构前,我会先用SonarQube进行静态扫描,但工具只能发现约30%的问题。更关键的是人工代码走查,我总结了一套"五感检测法":
最近审计的一个订单处理系统就存在典型的"霰弹式修改"坏味道——每次支付方式变更都需要修改OrderService、PaymentProcessor、AuditLogger等6个类。通过引入策略模式,我们将相关修改收敛到单一支付策略配置文件中。
没有测试覆盖的重构就像高空走钢丝没有安全绳。我的经验法则是:
在重构一个金融结算系统时,我们先用WireMock模拟外部支付网关,再为所有金额计算路径添加了边界测试。这后来帮助我们捕获了三次重构引入的零值处理错误,避免了可能的上百万损失。
对于单体应用,我采用"绞杀者模式":
在改造一个CMS系统时,我们先用垂直切片的方式将内容管理模块独立为微服务,六个月内完成了80%流量的迁移,整个过程用户无感知。
数据库重构最考验手艺:
最近完成的用户画像系统重构中,我们将宽表拆分为星型模型,查询性能提升了8倍,存储空间减少60%。
好代码应该像优秀的散文:
我要求团队遵循"30秒原则":任何一个有经验的开发者应该在30秒内理解方法的核心意图。这比任何代码规范都有效。
根据十五年经验总结的"重构决策矩阵":
code复制| 修改频率\复杂度 | 低 | 高 |
|----------------|----------|----------|
| 高频 | 立即重构 | 计划重构 |
| 低频 | 暂不处理 | 文档警示 |
去年我们就是据此决定优先重构了每天执行数万次的优惠券核销逻辑,而不是很少修改的报表导出功能。
在某金融项目中,我们配置了Sonar的质量阈,成功将代码重复率从35%持续控制在5%以下。
推行"童子军规则":每次修改代码都要让它比来时更干净。具体实践包括:
经过半年培养,团队的技术债务新增量下降了75%,这比重构本身带来的收益更为持久。