重构是在不改变外部行为的前提下,改善代码内部结构的过程。Martin Fowler 在《重构》一书中将其定义为软件开发中最重要的技能之一。
何时应该重构?
- 添加新功能时发现现有代码难以扩展
- 修复 Bug 时发现同一区域反复出问题
- Code Review 中发现设计缺陷
- 代码阅读理解成本过高
代码坏味道(Code Smells)
Kent Beck 和 Martin Fowler 总结了常见的代码坏味道,识别它们是重构的第一步:
过长函数
一个函数超过 20-30 行,通常意味着它承担了过多职责。解决方案:提取函数(Extract Function)。
重复代码
相同的逻辑出现在多处,修改时容易遗漏。解决方案:提取公共函数或创建抽象。
过大的类
一个类包含过多属性和方法,违反单一职责原则。解决方案:拆分为多个小类。
过长参数列表
函数参数超过 3-4 个,说明可能需要引入参数对象或 Builder 模式。
小步重构策略
重构的关键是「小步前进,频繁验证」:
- 确保测试覆盖:没有测试的代码不要重构
- 每次只做一个小改动:改完立即运行测试
- 使用 IDE 重构工具:重命名、提取方法、移动类都有自动化支持
- 提交频繁:每个成功的重构步骤都是一次 commit
常用重构手法
// 重构前:魔法数字
if (user.age >= 18) { ... }
// 重构后:命名常量
const LEGAL_AGE = 18;
if (user.age >= LEGAL_AGE) { ... }
// 重构前:嵌套条件
if (user) {
if (user.isActive) {
if (user.hasPermission('edit')) { ... }
}
}
// 重构后:卫语句(Guard Clauses)
if (!user) return;
if (!user.isActive) return;
if (!user.hasPermission('edit')) return;
// 主逻辑...
「任何时候,如果你看到代码并觉得『这里可以更好』,那就去改。不要等『重构日』。」—— Martin Fowler
重构与性能
大多数情况下,清晰的代码不会牺牲性能。如果重构后确实出现性能问题,再用 profiling 工具定位瓶颈,进行有针对性的优化——这就是「先让它工作,再让它正确,最后让它快」。