重构:改善既有代码的设计(第 2 版)

Martin Fowler(马丁·福勒)
1 阅读 0 点赞 2026-04-23 IT 虾讯 AI
重构代码质量Martin Fowler坏味道编程经典

《重构》是软件开发领域的经典著作,由 Martin Fowler 于 1999 年首次出版,第 2 版于 2018 年全面更新。重构是指在不改变代码外部行为的前提下,改善其内部结构的过程。本书详细介绍了 60 多种重构手法,每种手法都包含动机、操作步骤、示例代码和注意事项。第 2 版最大的变化是使用 JavaScript 作为示例语言,并增加了函数式编程相关内容。本书强调重构应该与开发并行,是持续改进代码质量的重要手段。学习重构可以帮助程序员识别代码坏味道,掌握改进技巧,写出更清晰、更可维护的代码。

本书速读

📖 本书核心内容

《重构:改善既有代码的设计》(Refactoring: Improving the Design of Existing Code)是软件开发领域的经典著作,由 Martin Fowler 于 1999 年首次出版,第 2 版于 2018 年全面更新。重构是指在不改变代码外部行为的前提下,改善其内部结构的过程。本书详细介绍了 60 多种重构手法,每种手法都包含动机、操作步骤、示例代码和注意事项。第 2 版最大的变化是使用 JavaScript 作为示例语言,并增加了函数式编程相关内容。本书强调重构应该与开发并行,是持续改进代码质量的重要手段。学习重构可以帮助程序员识别代码坏味道,掌握改进技巧,写出更清晰、更可维护的代码。正如 Fowler 所说:"重构不是大扫除,而是小步快跑的持续改进。"

🎯 核心观点一:什么是重构

重构的定义:重构是一种对软件内部结构的调整,目的是在不改变代码可观察行为的前提下,提高其可理解性、降低修改成本。重构的关键是"小步快跑":每次只做小的改动,改动后立即测试,确保没有破坏现有功能。重构不是重写:重写是推倒重来,重构是在现有基础上改进。重构不是优化:优化的目的是提高性能,重构的目的是提高可理解性和可维护性。重构应该与开发并行:在添加新功能之前,先重构现有代码,让新功能的添加更容易。重构是持续的过程:不是一次性的活动,而是日常开发的一部分。

分模块深入讲解

1. 代码坏味道(Code Smells):坏味道是代码中可能存在的问题信号,如重复代码、过长函数、过大类、过长参数列表、发散式变化、霰弹式修改、依恋情结、数据集群、基本类型偏执、switch 语句、平行继承体系、冗余类、夸夸其谈未来性、过多注释等。识别坏味道是重构的第一步,它告诉我们哪里需要改进。

2. 提炼函数(Extract Function):将一段代码提取为独立函数,并用函数名说明其意图。这是最常用的重构手法,可以让代码更清晰、更可复用。操作步骤:创建新函数、将代码复制到新函数、在原位置调用新函数、测试。适用场景:代码块有明确的职责、代码重复、需要提高可读性。

3. 搬移函数(Move Function):将函数从一个类移动到另一个类,当函数与目标类的关系更密切时使用。操作步骤:检查函数使用的数据、确定目标类、修改函数签名、移动函数、测试。适用场景:函数与源类关系弱、与目标类关系强、提高内聚性。

4. 以对象取代基本类型(Replace Primitive with Object):将基本类型(如字符串、数字)替换为对象,当基本类型承载了额外逻辑时使用。操作步骤:创建新类、将基本类型封装到新类、修改使用位置、测试。适用场景:基本类型有验证逻辑、有计算逻辑、需要扩展行为。

5. 拆分变量(Split Variable):当一个变量被用于多个不同目的时,将其拆分为多个变量。操作步骤:识别变量的不同用途、为每个用途创建新变量、替换使用位置、测试。适用场景:循环变量被复用、临时变量承载多个值、提高代码清晰度。

6. 引入参数对象(Introduce Parameter Object):将一组相关参数封装为对象,当函数参数过多时使用。操作步骤:创建参数类、修改函数签名、修改调用位置、测试。适用场景:参数数量超过 3 个、参数经常一起传递、提高函数可读性。

7. 移除中间人(Remove Middle Man):当一个类过多地委托给另一个类时,直接调用被委托的类。操作步骤:识别过度委托、修改调用位置、移除委托函数、测试。适用场景:委托链过长、增加不必要的复杂度、简化调用路径。

实践指南

  • 步骤 1:建立测试保护:重构之前,确保有充分的测试覆盖。测试是重构的安全网,可以在重构后验证功能是否正确。如果没有测试,先编写测试,再开始重构。测试驱动开发(TDD)是重构的最佳搭档。
  • 步骤 2:识别坏味道:定期审查代码,识别坏味道。坏味道是重构的信号,告诉我们哪里需要改进。常见的坏味道包括:重复代码、过长函数、过大类、过长参数列表、发散式变化、霰弹式修改等。
  • 步骤 3:选择重构手法:根据坏味道选择合适的重构手法。例如,重复代码用提炼函数,过长参数列表用引入参数对象,过大类用提炼类。每种重构手法都有明确的动机和操作步骤,按照步骤执行可以降低风险。
  • 步骤 4:小步快跑:每次只做小的改动,改动后立即测试。小步快跑的好处是:如果出现问题,可以快速回退;改动小,测试容易通过;心理压力小,更容易持续进行。不要试图一次重构太多,那样容易出错且难以调试。
  • 步骤 5:持续重构:重构不是一次性的活动,而是持续的过程。每次修改代码时,都应该问自己:能否让代码更好?能否消除坏味道?能否提高可读性?"童子军规则":让营地比你来时更干净。每次离开代码时,让它比你发现时更好一点。

⭐ 金句摘录

"重构是一种对软件内部结构的调整,目的是在不改变代码可观察行为的前提下,提高其可理解性、降低修改成本。"
"重构不是大扫除,而是小步快跑的持续改进。"
"代码坏味道是重构的信号,告诉我们哪里需要改进。"
"童子军规则:让营地比你来时更干净。"
"重构应该与开发并行,在添加新功能之前,先重构现有代码。"
"测试是重构的安全网,没有测试的保护,重构就是冒险。"
"好的代码是写出来的,更是改出来的。"

📚 阅读建议

本书适合以下人群阅读:所有层次的程序员:无论经验多少,都能从重构中受益;代码审查者:需要识别坏味道并指导团队成员改进;技术负责人:需要建立团队的代码质量文化和重构习惯。建议重点阅读:

  • 第 1-2 章(重构基础):理解重构的定义、原则、与测试的关系,适合所有读者精读。
  • 第 3 章(代码坏味道):学习识别各种坏味道,这是重构的第一步,适合所有读者反复阅读。
  • 第 4-6 章(重构手法):掌握常用重构手法的操作步骤,如提炼函数、搬移函数、引入参数对象等,建议边读边实践。
  • 第 8 章(重构、复用和继承):理解重构与设计模式的关系,适合中级以上读者。

读完本书,你将获得:1)识别代码坏味道能力,能够快速发现代码中的问题信号;2)系统的重构手法知识,掌握 60 多种重构技巧,能够在日常工作中立即应用;3)持续改进代码质量的习惯,让重构成为开发流程的一部分;4)提高代码可维护性的能力,写出更清晰、更易读的代码。正如 Fowler 所说:"任何傻瓜都能写出计算机能理解的代码,但只有好程序员才能写出人类能理解的代码。"这本书值得每个程序员放在案头,反复阅读,不断实践。