马丁·福勒的《重构》是软件工程领域的经典之作,出版二十多年来一直被奉为程序员的必读书。

但经典不等于每个人都适合读,也不等于读了就一定有收获。我身边有朋友说这本书改变了他的编程方式,也有朋友说读了一半就读不下去了,觉得都是些琐碎的技巧。

这篇文章我想给一个真实的评价,说说《重构》这本书到底好在哪里,有什么不足,适合什么人读,怎么读效果最好。如果你正在考虑要不要读这本书,希望这篇文章能帮你做出决定。

这本书讲了什么

先简单介绍一下这本书的内容。

《重构》的全称是《重构:改善既有代码的设计》,第一版出版于1999年,第二版在2018年出版,把示例代码从Java改成了JavaScript。作者是马丁·福勒,一位资深的软件工程师和技术思想家。

这本书的核心观点是:重构是一种有纪律的代码整理方式,在不改变代码外部行为的前提下,改善代码的内部结构。重构不是重写,不是推翻重来,而是在保持功能不变的前提下,一步步地改善代码的质量。

书的前半部分讲重构的原理,包括什么是重构、为什么要重构、什么时候重构、重构的原则和注意事项。后半部分是重构的目录,列出了几十种具体的重构手法,每种手法都有名称、动机、做法和示例。

这本书的定位不是教你怎么写新代码,而是教你怎么改善已有的代码。对于每天都在和遗留代码打交道的程序员来说,这本书的价值非常大。

好在哪里

先说说这本书好在哪里。

第一个好处是建立了重构的话语体系。在这本书之前,程序员们也会整理代码,但都是凭感觉,没有统一的术语和方法。福勒在这本书里给各种重构手法起了名字,比如"提取函数""内联变量""搬移函数""以多态取代条件表达式"等。有了这些名字,程序员之间讨论代码改进的时候就有了共同语言,可以说"这里应该提取一个函数",而不是说"这里应该整理一下"。这种话语体系的建立,对整个行业的影响是深远的。

第二个好处是把重构变成了有纪律的过程。很多人重构代码就是凭感觉改,改着改着就改出了bug,最后还不如不改。福勒在书里强调,重构应该是小步快跑的,每一步都很小,每一步之后都要运行测试,确保没有破坏功能。这种有纪律的重构方式,让代码改进变得安全可控。读完这本书之后,你会对重构有全新的认识,不再是"大改一通然后祈祷没问题",而是"小步改进随时可回退"。

第三个好处是培养了代码的"坏味道"嗅觉。书里有一章专门讲代码的坏味道,列出了二十多种常见的代码问题,比如重复代码、过长函数、过大的类、过长的参数列表、发散式变化等。这些坏味道就是需要重构的信号。读完这本书之后,你看代码的眼光会变,以前觉得没问题的代码,现在能一眼看出哪里有问题,哪里需要改进。这种能力的提升是潜移默化的,但影响非常大。

第四个好处是具体的重构手法很实用。书后半部分的重构目录,每一种手法都有详细的做法和示例。遇到需要重构的场景,可以直接翻到对应的手法,按照步骤一步步来。这些手法都是经过实践验证的,照着做基本不会出错。对于新手来说,这部分就像是一本操作手册,非常实用。

第五个好处是改变了对代码质量的态度。很多程序员觉得代码能跑就行,不愿意花时间整理代码。读了这本书之后,你会认识到代码质量的重要性,理解"技术债务"的概念,愿意在日常工作中花时间重构。这种态度的改变,比具体的技巧更重要。

有什么不足

当然,这本书也不是完美的,也有一些不足。

第一个不足是部分内容已经过时。这本书第一版是1999年写的,虽然2018年出了第二版,但有些观念还是带有那个时代的烙印。比如书里对动态语言的一些看法,现在看来已经不太适用了。还有一些重构手法,在现代IDE的支持下已经变得很简单,不需要手动一步步来做了。

第二个不足是示例代码偏简单。书里的示例都是为了说明重构手法而设计的小例子,和真实项目中的复杂代码有差距。真实项目中的代码往往耦合更严重、依赖更复杂,重构的难度比书里的例子大得多。读完书之后,你可能会觉得"道理我都懂,但真实代码还是不知道怎么改"。

第三个不足是缺乏对大规模重构的讨论。书里讲的都是函数级、类级的小重构,对于模块级、系统级的大规模重构讨论得比较少。但真实项目中,最需要重构的往往是整个模块或者整个系统的架构,这种大规模重构比小重构复杂得多,也危险得多。这方面的内容书里涉及不多。

第四个不足是测试的部分讲得不够。重构的前提是有可靠的测试,但书里对怎么写测试、怎么建立测试覆盖率讲得比较简略。如果你的项目没有测试,读了这本书之后可能还是不敢重构,因为没有测试保护,重构就是在冒险。

第五个不足是读起来可能有点枯燥。特别是后半部分的重构目录,一种手法接一种手法,读起来像是在看说明书。如果从头到尾通读,可能会觉得无聊。更适合的读法是当作工具书,需要的时候再翻。

适合谁读

根据我的阅读体验,这本书特别适合以下几类人。

第一类是工作了一到三年的程序员。这个阶段的程序员已经能写代码了,但代码质量还有很大的提升空间。读这本书能帮你建立良好的编程习惯,培养代码质量意识,避免写出"能跑但难维护"的代码。

第二类是每天和遗留代码打交道的程序员。如果你的工作主要是维护老系统、改老代码,那这本书简直是为你量身定做的。书里的重构手法能帮你安全地改善老代码,让维护工作变得不那么痛苦。

第三类是想提升代码质量的团队。如果团队的代码质量参差不齐,技术债务越积越多,可以组织团队一起读这本书,建立共同的重构话语体系和代码质量标准。很多团队的代码质量问题,本质上是没有共同的质量标准和改进方法。

第四类是想成为技术专家的程序员。如果你想在技术上深入发展,代码质量是基本功。重构的能力是技术专家的核心能力之一,这本书是学习重构的最好起点。

不太适合的人:一是完全的编程新手,如果你还在学语法和基础,这本书可能有点早,先把基础打牢再读;二是只做原型和Demo的程序员,如果你的代码写完就扔,不需要长期维护,那重构的价值不大;三是完全不写代码的管理者,虽然了解一下重构的概念有好处,但这本书的细节对你来说可能太技术了。

怎么读效果最好

如果你决定读这本书,我有几个阅读建议。

第一,先读前半部分,后半部分当工具书。书的前半部分讲重构的原理和原则,这部分要认真读,理解重构的思想和方法。后半部分的重构目录不需要通读,用到的时候再翻就好。

第二,边读边实践。读这本书的时候,最好手里有一个可以练习的项目。读到一种重构手法,就去自己的代码里找一找有没有类似的坏味道,然后动手重构一下。光读书不实践,是学不会重构的。

第三,配合测试来学。重构的前提是测试,读这本书的时候最好同时学习一下单元测试。学会写测试之后,重构才有安全网,才能放心地改代码。

第四,和同事一起读。如果能组织几个同事一起读,定期讨论,效果会更好。每个人对重构的理解不同,讨论能加深理解,也能在团队里建立共同的话语体系。

第五,不要追求一次读完。这本书不适合一口气读完,特别是后半部分。可以每天读一点,慢慢消化。重构是一种需要长期练习的技能,不是读一遍书就能掌握的。

我的阅读体验

说说我自己读这本书的体验。

我第一次读这本书是在工作第二年的时候。那时候我已经能写代码了,但写出来的代码自己都不想看,一个函数几百行,复制粘贴到处都是。读了这本书之后,我才知道原来代码可以写得这么干净,原来整理代码是有方法的。

读完之后我做的第一件事,就是把自己负责的一个模块重构了一遍。按照书里的方法,先补测试,然后一个坏味道一个坏味道地改,提取函数、消除重复、简化条件表达式。重构完之后,代码行数减少了三分之一,可读性和可维护性提升了很多。那种成就感是很难形容的。

从那以后,重构就成了我日常工作的一部分。每次改代码的时候,我都会顺便重构一下周围的代码。不是大张旗鼓地重构,而是"童子军规则":离开的时候让代码比你来的时候更干净。

现在回头看,这本书对我的影响是深远的。它不仅教给我具体的重构手法,更重要的是改变了我对代码质量的态度,让我从"能跑就行"变成了"追求代码之美"。这种态度的改变,让我在后来的职业生涯中受益无穷。

当然,我也不是说这本书是万能的。工作中遇到的很多复杂场景,书里并没有直接的答案。但书里的思想和方法,给了我解决问题的框架和思路。遇到复杂的重构问题,我会按照书里的原则,小步快跑、随时测试、持续集成,一步步地改善代码。

和其他书的对比

如果你读过其他软件工程的书,可能会想知道这本书和它们有什么不同。

和《代码整洁之道》相比,《代码整洁之道》更侧重于写新代码的时候怎么写得干净,而《重构》更侧重于改善已有的代码。两本书是互补的,建议都读。

和《设计模式》相比,《设计模式》讲的是经典的设计模式,而《重构》讲的是代码改进的手法。重构的过程中经常会用到设计模式,但两本书的侧重点不同。

和《程序员修炼之道》相比,《程序员修炼之道》更宏观,讲的是程序员的职业素养和思维方式;《重构》更具体,讲的是代码层面的具体技巧。

如果只能选一本,我会推荐《重构》,因为它最实用,读完就能用。但如果有时间,这几本书都值得读。

第二版和第一版怎么选

最后说一下版本选择的问题。

《重构》有两个版本,第一版是1999年出版的,示例代码是Java;第二版是2018年出版的,示例代码是JavaScript,内容也做了一些更新。

我的建议是直接读第二版。原因有几个:第一,第二版的内容更新,加入了一些新的重构手法,去掉了一些过时的内容;第二,JavaScript比Java更简洁,示例代码更容易看懂;第三,第二版的排版和印刷更好,阅读体验更好。

当然,如果你主要用Java开发,第一版的示例可能更亲切一些。但重构的思想和手法是语言无关的,用什么语言的示例其实影响不大。

还有一点,第二版比第一版薄一些,因为作者去掉了一些不太常用的重构手法,把内容精简了。对于大多数读者来说,第二版的内容已经足够了。

写在最后

《重构》是一本值得每个程序员认真读的书。

它不会让你立刻变成编程大神,也不会教你什么高深的技术。但它会改变你写代码的方式,提升你对代码质量的认知,让你写出更干净、更易维护、更有美感的代码。

在这个追求快速迭代的时代,很多人不愿意花时间重构代码,觉得那是浪费时间。但技术债务是会累积的,今天不重构,明天就要花十倍的时间来还债。重构不是浪费时间,而是投资未来。

如果你还没有读过这本书,我推荐你读一读。如果你已经读过了,也建议你每隔一段时间重读一遍,每次读都会有新的收获。

最后用马丁·福勒的一句话来结束这篇文章:"任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员。"

愿每一个程序员,都能写出人类容易理解的代码。