← 全部书单 / 软件工程

《重构:改善既有代码的设计》

《重构:改善既有代码的设计》封面
作者: 马丁·福勒
出版社: 中国电力出版社
出版年: 2003-8-1
原作名: Refactoring: Improving the Design of Existing Code
9
★★★★★
豆瓣评分 · 2,131 人评价
未标记阅读状态
把“能跑但难看”的代码,一小步一小步改成“好看又好改”:不改变功能,只改善结构。

总体观点

1999 年,马丁·福勒把程序员口口相传、没人系统总结过的“整理代码”手法写成书。在此之前“重构”只是高手间的黑话,之后成了每个程序员敢写进简历的正式手艺。

核心观点一句话:不改变软件外部行为的前提下,改善内部结构。用户感觉不到变化,代码更好懂、更好改。几十种手法条条讲清:什么情况用、为什么用、怎么做。

它回答了所有程序员的纠结:“代码太烂,推倒重写还是忍着?”福勒说:别走极端,小步快走,一次改一点,每步都保证能跑。“代码坏味道”这个词也是他发明的。

核心观点

  1. 1. 重构不改变功能,只改善结构

    铁律:改完后软件从外面看必须和原来一模一样——同样输入,同样输出。变的只是代码内部长什么样。

    给房子重新布线:住户感觉不到变化,但电工再也不用在乱麻一样的电线里找火线了。
  2. 2. 先闻闻代码有没有“坏味道”

    福勒列了 22 种“代码坏味道”:重复代码、超长函数、参数太多……坏味道不是 bug,代码能跑,但它在提醒你:这里以后会出事。

    函数有 8 个参数:createOrder(用户编号, 用户名, 手机号, 地址……)——调用容易传错,改起来提心吊胆。打包成“订单信息”对象。
  3. 3. 小步快走,每步都能跑

    最忌“憋大招”——改三天中间代码一直是坏的,最后祈祷别炸。每步小到不可能出错,改完立刻跑测试确认,再走下一步。

    把类拆成两个:新建空类→跑测试→搬一个方法→跑测试→再搬一个。哪步出问题,就是这步的锅,回滚也只回滚一步。
  4. 4. 戴两顶帽子,别混着戴

    “加功能”和“重构”是两顶帽子:戴加功能的帽子只加功能,别顺手改结构;戴重构的帽子只改结构,别顺手加功能。混着做,出 bug 分不清是谁的锅。

    加“优惠券”功能发现旧代码太乱:先戴重构帽整理好、测试通过、提交;再换加功能帽,在新结构上加优惠券。分两步,每步都清楚。
  5. 5. 三次法则:事不过三再抽象

    第一次写一段代码,第二次发现类似代码又写一遍,第三次——动手抽象成可复用的。不到三次急着抽象容易抽象错,三次还不动手就是在养坏味道。

    “校验手机号”逻辑在注册页、修改资料页、找回密码页出现三次:别再复制,抽成一个函数。规则一变,改一处就行。
  6. 6. 重构不是重写,别推倒重来

    看到烂代码就想全删重写,风险极大:旧代码藏着无数“只有它知道”的业务细节和坑,重写等于全扔了。重构渐进式:旧系统一边跑,一边被一点点替换,风险可控。

    十年老计费系统没人敢动。重写派八个月还没摸清特殊折扣规则,新系统上线第一天就算错账。重构派一个模块一个模块整理,老系统一直在线,稳稳过渡。
  7. 7. 拾穗式重构:顺手的事天天做

    重构不用立项排期开大会。改 bug、加功能时路过烂代码,顺手花十分钟整理一下,像农民收麦顺手捡麦穗。每天捡一点,质量不知不觉上去。

    修 bug 看到变量名 temp1、temp2,顺手改成 orderTotal、discountAmount。没多花几分钟,下一个读代码的人省十分钟琢磨。
树状思维导图

全书思维导图 · 知识脉络树

💡 拖拽平移 · 滚轮缩放 · 点击分支圆点折叠/展开
已复制思维导图大纲到剪贴板!

全书结构

  1. 第1章 重构,第一个案例

    以经典的影片出租计费程序为例,演示提炼函数与搬移方法,步步为营且始终保持单元测试全绿。

    面对数百行交织了格式化打印与计费逻辑的复杂方法,先提炼出小函数,再搬移到影片类中,代码结构瞬间清晰。
  2. 第2章 重构原则

    重构是在不改变软件可观察行为的前提下改善其内部结构;戴两顶帽子分别处理功能添加与结构优化。

    上午戴“添加功能”帽子专注编写新业务逻辑,下午戴“重构”帽子整理早上的重复代码并运行全量单测验证。
  3. 第3章 代码的坏味道

    精准识别神秘命名、重复代码、过长函数、过长参数列、发散式变化、霰弹式修改等22种坏味道。

    新增一种优惠券折扣类型需要修改七八个不同类的多处代码(霰弹式修改),表明该计算策略需要内聚封装为独立对象。
  4. 第4章 构筑测试体系

    自测试代码是重构的安全网,通过完备的自动化单元测试快速发现由于重构带来的非预期破坏。

    在动手重构核心结算引擎前,先补充三十组涵盖各种折扣边界的测试用例,确保后续每一次结构调整心里有底。
  5. 第5章 重构列表

    规范重构手法百科的组织结构,统一涵盖重构名称、动机、做法步骤与范例的标准描述格式。

    查阅标准重构手法卡片,按照给出的详细操作步骤逐步实施安全变换,避免凭经验乱改引入隐蔽 bug。
  6. 第6章 重新组织函数

    提炼函数(Extract Method)、内联函数、引入解释性变量以消除冗长混杂的逻辑片段。

    将一个包含几十行参数校验和数据拼装的长函数,拆分为三个职责单一的小函数并赋予表达意图的自解释函数名。
  7. 第7章 在对象之间搬移特性

    搬移函数、搬移字段、提炼类与隐藏委托关系,让数据和操作归入最合适的责任归属主体。

    发现客户类频繁读取并操作订单对象的内部字段(依恋情结),将该计算逻辑直接搬移到订单类内部封装。
  8. 第8章 重新组织数据

    自封装字段、以对象取代基本类型、以常量替换魔法数,实现数据的严密抽象与自验证。

    代码中四处散落的原始字符串手机号,重构成带有格式校验与脱敏行为的 PhoneNumber 值对象。
  9. 第9章 简化条件表达式

    分解复杂条件、合并条件表达式、引入卫语句提前返回、以多态取代嵌套 switch 分支。

    将深层嵌套的四层 if-else,改用三行卫语句处理异常边界并提前 return,主干业务逻辑一览无余。
  10. 第10章 简化函数调用

    函数改名使其意图鲜明,分离查询函数与修改函数(命令查询分离),减少多余参数。

    将既修改数据库又返回用户详情的复杂函数,拆分为独立的 `updateUser` 与 `getUserDetail` 两个函数。
  11. 第11章 处理概括关系

    字段与方法上移下移、提炼超类、以委托取代继承以规避错误的继承层次。

    两个子类重复包含了一模一样的计费逻辑,果断将其上移至基类,彻底消除子类间的代码复制。
  12. 第12章 大型重构

    梳理复杂的继承层次、将过程化设计转化为领域对象、分离领域逻辑与表现层。

    把原本紧密捆绑在 Web 框架 Controller 中的上千行数据库操作与校验,彻底剥离为纯粹的领域服务层。
  13. 第13章 重构,复用与现实

    在实际商业交付压力下,如何向管理者证明重构价值并融入敏捷日常节奏,以持续重构支撑系统复用。

    在每个敏捷迭代中留出 20% 技术债清理预算,通过长期平稳重构维持系统交付速度不退化。
  14. 第14章 重构工具

    善用现代化 IDE 提供的自动化安全重构功能,结合单元测试体系提高重构效率与安全性。

    利用 IDE 的快捷键一键安全重命名或提取接口,自动处理工程中数十个引用处,避免手工全局替换遗漏。
返回 软件工程 目录

观点与结构均为转述总结,非原文摘录。封面图片来自豆瓣读书,仅作展示。

豆瓣评分与评价人数为逐本人工核实当天的数值。 · GitHub 仓库 · v1.0.0