作为程序员,对于《重构》一定并不陌生。尽管许多人把它奉为经典,例如有“改善代码的济世良方”、“隐藏的宝藏”等等好评如潮,但也不乏对它言词犀利的差评,有些甚至尖酸刻薄,例如“内容虽好但是写得太烂”、“肤浅、冗长、且好高骛远”等等。为何读者的评论会出现如此巨大反差?真相到底是什么?答案尽在“评论之评论”中为您揭晓 :D

作为程序员,对于《重构》一定并不陌生。尽管许多人把它奉为经典,例如有“改善代码的济世良方”、“隐藏的宝藏”等等好评如潮,但也不乏对它言词犀利的差评,有些甚至尖酸刻薄,例如“内容虽好但是写得太烂”、“肤浅、冗长、且好高骛远”等等。为何读者的评论会出现如此巨大反差?真相到底是什么?答案尽在“评论之评论”中为您揭晓 :D

顺便说一句,俺把“好书评”改成了“好书评”的原因有二:一、好评、差评的译文总共加起来有7000余字,实在不短;二、原来的“短”字仅表示字数多寡,而改为“妙”字则能体现出内容之趣。

:本文书评均译自原书Amazon书评,收录日期为2012年04月28日。根据Amazon上评论的排名顺序,分别选出名列前茅的好评、差评各5篇与大家分享于此!

好评

★★★★ 改善代码的济世良方

评价日期:2000年05月05日
合计144人顶,6人踩。

正如“四人帮”(Gang of Four)那本里程碑式的著作《设计模式》(Design Patterns)一样,Fowler和他的死党已经创建了另一本编目式图书,而这次的主题是重构(refactoring)。

重构(Refactoring)是指,拿来现有的工作软件,并以改善其设计为目的进行改造,以便将来的修改和增强更容易添加进去。《重构》从根本上说是包含了大约70种不同种类改进方法的编目,那些改进方法都可用于开发面向对象软件。

编目中的每个词条均描述了实现问题、解决方案、应用解决方案的动机、重构的作法、以及范例。书中的范例都是用Java编写的,不过C++程序员应该可以轻而易举地研究这些重构方法。Fowler通常会用UML图来说明各种重构方法,因此对一建模语言略知一二将会对你大有裨益。

尽管此编目很不错,而且在大多数情况下各种重构方法显而易见。甚至具有一定经验的程序员无需按部就班地照着作法所述的那样去做。然而,真正的好处在于,每种重构方法的作法有助于保证你可以在不引入新错误或副作用的情况下重构成功。比起大多数开发者自然采用地那些更粗糙的重构方法,他们鼓励你采取若干较小的、可验证步骤来完成重构。其实你这么做可以节省时间。

你怎么知道你的重构是安全的?Fowler等人给出的答案是单元测试(Unit testing)。Java开发者将会发现引入的JUnit测试框架是此书最有价值的部分,甚至超过了重构编目本身。

当然,书中除了编目和JUnit之外,还有更多内容。书中讨论了重构的历史、如何评估各种重构工具、以及如何说服管理部门,那些看似是开销活动重构工作从长远来看实际上是有用的。

很遗憾,这几个章节都过于简短。而且没有讨论如何将重构融入不同的软件开发过程。例如,对于使用极限编程(Extreme Programming,XP)的程序员,当他们与单元测试一起配套使用Fowler的重构建议时,可能感觉就像在家一样轻松自如。不过对于那些坚持如PSP(即Personal Software Process,个体软件过程)等软件工程协会过程的开发者而言,他们会把测试所用时间归为故障时间,而即便与之相关的工作无法避免,那么测试时间也要最小化。而净室开发者所受的教导是,单元测试会干扰对质量的度量,并且对于单元测试的验证又该如何去做。这些开发者是否要在每次重构之后重新验证呢?对于这些问题书中并未给出答案。

第3章“代码的坏味道”是非同寻常的一章,这一章给出各种重构方法的所有动机。对于“Long Method(过长函数)”或“Lazy Class(冗赘类)”等诸如此类的模糊概念,恰恰是它们在谈笑风生间为你着手重构提供了基础。我之所以说“谈笑风生”,主要是因为Beck和Fowler所用的那些稀奇古怪的类比(类之间变得过于亲密,以至于探究起彼此的私密之处)常常让人忍俊不禁(只用一章来讨论代码的“坏味道”似乎感觉意犹未尽)。

总体而言,我很喜欢读这本书,而且每当我把单元测试和各种重构方法付诸实践时也会参阅此编目。Fowler的写作风格如行云流水,而且内容通俗易懂。此书不仅排版干净利落、图表一清二楚,而且重构索引和“味道”索引都可谓功效不凡!


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

评价日期:2002年11月11日
合计101人顶,9人踩。

不久以前,有人向我提到了一个闻所未闻的词,即重构。还告诉我,为了能更好地了解理解重构的含义,最好找本Martin Fowler的书读一读。我已读过此书,朋友们,我想应该把此书算作“隐藏的宝藏”。

尽管没有华而不实或是众所周知的书名,但是我相信,与那些主流的、更受欢迎的技术图书相比,其影响力一定会更为深远。其传授的基础理论可受用多年,即便语言变更亦是如此。

关于此书,我觉得有仅几件事值得推敲,详述如下。

前言

前言开门见山,给出了重构一词的定义。良好的开端是成功的一半,因为你已获得了重构的确切定义。简言之,重构是这样一个过程:在不改变代码外在行为的前提下,对代码进行修改,从而改善其内部结构。

第1章 重构,第一个案例

在这一章中Fowler先生试图从一个简单的重构示例开始。而问题在于这章犹如滔滔江水连绵不绝,竟然写了50多页。尽管Fowler先生解释了这样做的原因,但是我仍然认为,简单示本就该非常简单。尤其是作为本书的首章更应如此。我绝无说此章不好之意。我只是觉得此章在书中出现得为时过早。换做是我,我会把它作为最后一章。

第2章 重构原则

这是很棒的一章。不仅讨论了重构的定义,还谈到了以下问题:为何重构?何时重构?怎么对经理说?最后这个问题可能看上去很可笑,不过只要你读了此章,自然就会明白其中的玄机。这章还讨论了一些出现在重构期间的常见问题、以及重构与性能。

第3章 代码的坏味道

这一章讨论了会使代码“散发味道”的一些东西。每当代码“散发味道”,那就是需要进行重构的迹象。一共讨论了22种不同的“味道”。我最喜欢的是,Duplicated Code(重复代码) 、Large Class(过大的类)、还有Lazy Class(冗赘类)。这章中满是令人拍案叫绝的隐喻。

第4章 构筑测试体系

构筑测试体系是重构的重要组成部分。重构是以小步推进,而且每一步完成后你都要测试。在这一章中讨论了与重构时应用测试有关的过程和方法。

第5章 重构列表

这一章是对6至12章的快速介绍。Fowler先生解释了每种重构的分类方法。他花了许多时间来命名并详细解释每种重构,这真是令人叹为观止。

第6章 重新组织函数

我最爱的章节之一。Fowler先生开门见山地说道,“重构的很大一部分工作就是撰写函数,以便妥善地把代码包装起来。”这章一共解释了9种重构方法。其中我最爱的是Inline Method(内联函数)和Extract Method(提炼函数)。

第7章 在对象之间搬移特性

有时你需要将某些东西从一个对象移动到另一个对象。这章讨论了在对象之间搬移特性的技巧。一共讨论、详述了8中重构方法。这章中我最爱的是Extract Class(提炼类)。

第8章 重新组织数据

这是篇幅很大的一章,其中对16种重构方法进行了细致入微的讨论,这些方法会让数据处理变得得心应手。这章中显而易见的一点是,某些特定的重构方法可以彼此对调。例如Change Value to Reference(将值对象改为引用对象)和Change Reference to Value(将引用对象改为值对象)两种方法就恰恰说明了这一点。因此对于一些重构方法不能高“一刀切”,而要因势利导。

第9章 简化条件表达式

由于在编程世界中条件逻辑已是司空见惯,因此这章十分有用。因为条件逻辑存在将问题复杂化的倾向,所以这章介绍的8种重构方法会有助于简化它们。

第10章 简化函数调用

这章中的15种重构方法有助于教会我们如何使方法调用变得易如反掌。这些方法从非常简单的Rename Method(函数改名)到较为复杂的Replace Constructor with Factory Method(以工厂函数取代构造函数)。

第11章 处理概括关系

这里介绍了12种重构方法,用于处理由于概括关系(generalization)而形成的状况。其中还讨论了继承(Inheritance)、委托(Delegation)、以及接口(Interfaces)等主题。

第12章 大型重构

Kent Beck与Fowler先生二人合著此章。他们讨论了4种大型重构:Tease Apart Inheritance(梳理并分解继承体系)、Convert Procedural Design to Objects(将过程化设计转化为对象设计)、Separate Domain from Presentation(将领域和表述/显示分离)、以及Extract Hierarchy(提炼继承体系)。相对于前面几章中的小型的独立重构方法而言,这些重构方法则属于更加兼容并包的类型。二位高人竟然将通常要用长篇大论来解释的内容一言以蔽之,堪称功不可没!

第13章 重构,复用与现实

这章是由William Opdyke编写的。他不仅讨论了他的重构经历,还有比如为何开发者不愿重构、以及如何减少重构开销等其他主题。这章是“融会贯通”的绝妙一章,的确有助于高屋建瓴地审视书中观点。

第14章 重构工具

Don Roberts与John Brant合著了这一章。正如这章标题所示,他们讨论了重构工具。

第15章 总结

Kent Beck做了个4页的快速总结。

我觉得值得推敲的另一件事情是,我希望示例语言不是用Java而是用其他语言。我对Java一窍不通。对我而言,如果能用VB.net来编写示例,那么我读起来会更加驾轻就熟。幸好我深得其中要旨,当然这也是关键所在。

没错,如前所述,我把此书视为“隐藏的宝藏”。书中所探讨的内容会在未来几年帮助许多人写出更好、更易懂的代码。要是10分制,我会给此书打9.5分。此书的确物有所值!


★★★★★ 让老态龙钟的代码焕发青春

评价日期:2000年05月17日
合计24人顶,0人踩。

此书的基本论点是,实际运行的程序由于多种原因被设计得千疮百孔。那些程序出于各种各样的原因变成了这样。最初设计良好的软件,可能由于程序扩展而导致衰退。始料未及的复杂度可能导致超大的方法。正如Fowler所述,重构的功能就是防止程序发生衰退转变。由于这种转变是可逆的,因此我们的目的就是以某种方式改善程序质量。

尽管Fowler觉得重构程序是为了使得添加新功能变得更简单。然而重构程序同时也是为了使得人类读者更易理解。

他还主张小步推进、保持功能,而且同时要频繁使用详尽的测试套件来进行单元测试。

此书一半是由重构方法编目组成的。他给每种重构方法都起了令人难以忘怀的名字,例如“Replace Type Code with Subclasses(以子类取代类型码)”。他用两幅UML类图来对比说明设计转换,而且还用一组标准段落来解释:动机(Motivation)、作法(Mechanics)、以及范例(Example)。

动机(Motivation)是个平铺直叙的段落,对重构方法进行描述和论证,并展示与其他重构方法之间的关系。

作法(Mechanics)是执行重构所需的一系列步骤,并以要点列表的形式展示出来。对于某些要点他会展开解释。

范例(Example)是此书的价值所在。Fowler摘取了一些Java代码片段,并带领我们一步一步地完成重构。尽管未必他展示的每一步都能让我们心悦诚服,因而使得代码略显不足,但是从实用的角度来看就足够了。

对于非Java程序员而言,示例代码理解起来也是一目了然。他把代码解释得一清二楚,对于那种书中代码含义不直观的图书,此书完全可以充当Java教程使用。在那些重构方法中有一或两种方法是特定于Java对象模型的,而且不适用于其他语言。除了极少数语言特定的重构方法以外,其他语言皆可从类似的处理中获益。

此书大有《设计模式》运动之遗风,书中频繁引用了各种模式。重构方法的目的可能就是实现特定模式,或是利用特定模式。此书可作为《设计模式》教程使用。

我有几句话不吐不快。Fowler主张在为了某次代码评审而研究代码时使用重构。此时程序员的职业敏感性应该非常灵敏,尤其当他或她是新手时更是如此。审阅者应该在阅读代码的同时将重构铭记于心,并且可能还有一些重构建议,反而却要程序员去完成那些更改,真是岂有此理!

通过阅读此书,我已鼓起勇气着手重构自己的代码。我的错误突显出小步推进和频繁测试的必要性。根据Fowler给出JUnit测试框架,我花了一天时间来构建有效的Delphi测试框架。不过对于高度耦合的解析代码(parsing code)而言,此类方法似乎并不适用。尽管我可以提炼出一些小的代码块,但是它们彼此间仍然紧紧地耦合在一起,并且很难给出意味深长的名字。其中的答案可能是,没有使用自底向上的重构方法,而是使用了自顶向下的递归下降法(approach of recursive descent)。或许递归下降可以指导重构。因为大部分重构都是局部方法。有人几乎说是针孔方法。有时全局观是必需的。

总之,我想说此书堪称佳作,它不仅适合于那些对Java略知一二又满腹疑团的Java菜鸟,而且还适合于我们这些略显疲塌又需要新思想、新动力的老油条。


★★★★★ 不仅要读,更要买!

评价日期:2000年07月18日
合计38人顶,3人踩。

我们可能读到许多好书,要么关于特定技术(COM、UML等),要么关于特定编程语言,乃至关于不同的软件开发方法(RUP、OPEN等),然而经典之作会时不时地出现。就像《设计模式》4年前横空出世一样,现在《重构》随之而来。每位真正的面向对象开发者都应该拥有这两本书。请捧起《重构》,只要读一读第3章(代码的坏味道)就好了,因为其中总结了所有可能在不知不觉间侵入代码的“坏味道”。一共列举了21个关于编程的反面教材及其原因。此书的其余部分介绍了大量用于改变既有代码的技术(各种重构方法),从而消除“坏味道”。大多数重构方法都附有一些UML图示,从中足以领会重构之意图,而且随后还有Java代码示例。之所以成此书为杰作,是因为可以轻松地把它作为参考书来查询,由于作者正是出于此目的对它进行了精心设计,通过查询详尽的索引和表格就可以匹配到各种坏味道及相应的重构方法。这些对于《代码大全》(CODE COMPLETE)的读者是否有似曾相识之感,尽管《重构》的想法与之如出一辙,然而可谓更胜一筹。加之Fowler简洁诙谐的写作风格定会让您尽享轻松、快乐的阅读体验。真心实意地推荐此书!


★★★★★ 别愣着,像我一样该出手时就出手!

评价日期:2003年05月13日
合计19人顶,0人踩。

我得知此书已一年有余。起初,我以为此书与重建遗留系统有关。常言道,事不关己高高挂起,由于我的工作与此不沾边,因此也就没有重视此书。然而在过去的一年里,我总会无意中看到有人提到此书。似乎大家对此书交口称赞,现在我终于明白其中缘由了。

在做面向对象设计的时候,很容易陷入“分析瘫痪”(analysis paralysis)的怪圈。常常会听到这样的抱怨,“我已经创建了27幅不同的类图,还有42幅独立的时序图,但是我却没看见有任何书面代码产生……”极限编程(XP)的流行在一定程度上是因为,它让你付诸行动——你立即着手编码,而不是花上数周(或是数月)时间没完没了地创建类图。极限编程的宗旨就是“不妨先动手!”。

但是,要使这种“先编码,再提问”理念与至少需要做些设计工作的共识相一致,我们又该怎么做呢?在《重构》中,Martin Fowler给出了答案。他的做法是,先创建一些可工作的代码,然后仔细研究代码,以便找出可改进之处——即重构它。

以Fowler观点来看,在完成编码以前,你无法真正了解问题所在,因此不要把未来3周的时间花在为下一个任务视图找出完美模式上面,忘掉模式,而是动手编些代码。你至少要得到了一些可运行的代码以后,再考虑将某些模式重新融入到既有代码之中。

当然,这只是对此过程轻描淡写的简述,不过围绕着“重构”过程散发出预备—射击—瞄准(ready-fire-aim)过程的味道。而且看来切实可行——即使是那些对于极限编程其他核心实践不买账的人,他们的过程只要以重构为中心就可以了。

此书的重构方法编目为如何清理各种特定问题提供了一流的参考。不过就我而言,此书最有价值的部分是前50页。

Fowler以一个简单但糟糕的示例作为此书的开篇,然后他着手重构,逐步推进,并得到一些更为优雅的代码。如果你喜欢先学习各种原则,那么在通读此示例之前你会愿意读一下第2章(重构原则),不过我发现这是个非常有价值的练习。我建议用你所选择的语言编写此示例,然后与Fowler共同完成此示例的重构。

就像测试一样,总有一种把重构归为仅仅是另一种开发技术的倾向。不过正如测试一样,重构的核心开发理念是:“我知道我不会在第一遍就把它做好,因此我只要尽我所能去做就好了。那样做完以后,我会对如何改进它有更好的想法,而且我愿意那样做。不过会浪费一些时间,因此我要赶快行动。”

这种持续改进的理念使得开发者可以尽快开始行动,并降低由于延迟而导致失败的风险。Fowler的书堪称上上之作,它有助于开发者更快地创建更灵活的代码。我诚心诚意地向你推荐《重构》。

差评

★ 内容虽好但是写得太烂

评价日期:2000年03月15日
合计72人顶,24人踩。

对于如何在无需彻底重写代码的前提下改善既有代码的设计,书中给出了不少真知灼见,这完全不同于大多数UML类型图书的套路,那些书都主张完全改变设计和构建软件的方式。这并不是说设计和构建统一方法不好,只是说如果你不能掌控某个组织,那么要改变其运行方式会比登天还难。Fowler先生提出了一种机制,以便既可以改善既有代码的设计,又可以向其中添加功能。不过一旦断章取义,这些信息就会变得十分有用。然而此书既不是“范式转换”,也不是《设计模式》伴侣——尽管Fowler在整本书中经常提到《设计模式》,但是《重构》肯定不是为那些《设计模式》的读者写的。因为在Fowler给出的那些将糟糕代码转变为优质代码的示例中,从未用过一个出自《设计模式》的模式。此书适用于任何面向对象语言,尽管他在示例中使用的是Java,但是那些原则可以轻松映射到C++和SmallTalk。尽管几乎书中提到的所有技术都是常识,不过他却在书中用了很大篇幅以简单的术语来解释如何完成它们。对于每种“重构方法”,他都能用三言两语概述其过程,并给出代码片段或是类图来举例说明。不过由于他要煞费苦心地解释进行代码改进的过程,因此他的语气会变得谦逊起来。例如,书中的首个技术是Extract Method(提炼函数),其简明描述是:“[如果]你有一段可以组织到一起的代码片段……[那么]将这段代码放进一个函数中,并用函数名来解释其用途。”虽然相当简单,但是要想完全理解他所讲述的内容,这寥寥数语似乎还远远不够。然而随后,他用短小精干的代码片段做到了画龙点睛。至此需要大约半页。但是他却用了四页半来进一步解释如何完成这个简单的剪切-粘贴过程。在总共418页的书中,竟然用270页以此种不胜其烦的方式详细解释了72种重构方法。最有用的8页用于说明代码中那些会导致“重构”的坏“味道”。又用了110页来告诉你,如何向你的老板证明此工作的合理性、无论你的老板是否批准都鼓励你进行重构、倡导极限编程所特有的“测试——小改动——测试”的结对编程技术。最后30页由其他几位作者所著。总而言之,我认为此书应该“重构”为100至150页以内的软皮手册,这让人不禁想起Scott Meyers所著的Effective C++系列图书。如果你要找《设计模式:第2部》,那么此书肯定不是!全文完。


★★ 肤浅、冗长、且好高骛远

评价日期:2003年02月10日
合计28人顶,8人踩。

尽管此书试图从格式和效果两方面与《设计模式》匹配起来,然而很遗憾,它失败了。作者用了大量篇幅来解释一些微不足道的重构方法,例如Rename Method(函数改名)或是Replace Magic Number with Symbolic Constant(以字面常量取代魔法数)。任何具有一定经验的软件开发者现在就可以说出如何以及为何要执行那些任务,他们根本无需此书。此书并未涉及更为复杂或是稀奇古怪的重构方法,而那些方法对于经验丰富的开发者更有价值,而且书中也没有涉及重构可能对既有代码造成的影响、以及如何控制和最小化那些影响。

然而,书中对于使用重构来修正某些经典设计错误给出了一些真知灼见,这可能对于新手很有价值。那就给个2星吧!


★★ 也就50的书居然写出来400多页

评价日期:17, 2000年12月17日
合计20人顶,7人踩。

虽然主题一语中的,但是除此之外,此书应该有更多内容。有些页仅有4行代码;我搞不明白为什么要留那么多空白。传授的许多技术由来已久,而且本应就是开发和重构过程中的一部分。由于此书满是颠来倒去之语,因此要是作者们能认真检查彼此的手稿并“重构”,那就太好了。


★★★ 书名应为“适用于Java程序员的重构”

评价日期:1999年12月13日
合计11人顶,11人踩。

作为C++程序员,我发现许多示例与Java语言(对此我不太熟悉)的细节联系极为密切。我想要的是一本更有实质性的、通用的、面向对象编程图书。其中许多示例都属于面向对象编程的常识,所以此书看起来更适合作为学习Java编程的入门书,而不是为《设计模式》(堪称杰作)读者所写的。


★★★ 一本入门书

评价日期:2002年04月07日
合计11人顶,15人踩。

首先,此书对于理解重构的含义及其技术大有裨益。如果你是名菜鸟程序员,那么此书会对你十分帮助,它会告诉你如何重构、以及为何还有何时重构。

然而,问题就在于此书是本“书”。许多程序员对于书中的故事和技术都会有似曾相识之感。然而遗憾的是,书中的技术并不罕见。例如,书中竟然用了好几页来解释了如何创建临时变量以及如何消除它!对于程序员而言,此类内容不过是家常便饭。许多人根本不用学这个。

对于经验丰富的程序员而言,重构的问题之一是,重构意味着不添加功能却要“改变”既有代码。尽管给出了许多益处,但是重构也给出了一些问题。例如,在团队协作过程中,即便是改变方法名都是非常困难的,因为改名经常会导致源码中出现冲突。然而,此书对于此类问题并没有给出任何解决方案。

总之,我不会把此书推荐给经验丰富的程序员。

评论之评论

首先,非常感谢您能读到这里 :D

闲话少叙,正如您所看到的:为何外国读者的评论会出现如此巨大反差?真相到底是什么?

对于第一个问题其实并不难回答,“众口难调”四字足矣,当然用俗话说就是“萝卜白菜各有所爱”。除此之外,俺想多说一句,在差评中多位读者提到此书过于浅显,不适于经验丰富的程序员,更适于刚入门的菜鸟。其实仔细想想就能明白,两位主要作者Martin Fowler和Kent Beck都是敏捷社区的领军人物,总不能算是菜鸟吧?他们劳神费力写出的必定是自认为有价值的内容!二位牛人况且能一步一步地认真重构,可是为什么所谓“经验丰富的程序员”却做不到呢?答案很简单,他们骄傲了!(若您也有此苗头,不妨待会儿读读《禅修程序员十诫》。)

人的问题讲完了,回过头来认真分析一下此书到底有没有问题?

通过阅读评论可知,此书虽然多次提及《设计模式》,但是与之联系并不密切,正如有位差评读者所写“此书不是为《设计模式》(堪称杰作)读者所写的”。此书的重点在于苦练编码基本功,消除代码中“坏味道”。而对于志在修炼更高阶武功的读者,不妨读一读《重构与模式》,该书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式……

接下来分析一下“啰嗦”的问题,在好评、差评中都有人抱怨书中“废话太多”。当然每个人的时间都很宝贵,而Martin Fowler为何要费时又费力地写一堆废话呢?!莫非为了赚取稿酬?罪过罪过,还是不要“以小人之心,度君子之腹”了。话说《重构》最早是由中国电力出版社引进的,当时的译者是侯捷、熊节,当时侯捷老师在译序中也发表了同样的看法:

初阅读本书,屡屡感觉书中所列的许多重构目标过于平淡,重构步骤过于琐屑。这些我们平常也都做、习惯大气挥洒的动作,何必以近乎枯燥的过程小步前进?然后,渐渐我才体会,正是这样的小步与缓步前进,不过激,不躁进,再加上完整的测试配套(是的,测试之于重构极其重要),才是「不带来破坏,不引入臭虫」的最佳保障。我个人其实不敢置信有谁能够乖乖地按步遵循实现本书所列诸多被我(从人的角度)认为平淡而琐屑的重构步骤。我个人认为,本书的最大价值,除了呼吁对软件质量的追求态度,以及对重构「工程性」的认识,最终最重要的价值还在于:建立起吾人对于「目前和未来之自动化重构工具」的基本理论和实作技术上的认识与信赖。人类眼中平淡琐屑的步骤,正是自动化重构工具的基础。机器缺乏人类的「大局观」智慧,机器需要的正是切割为一个一个极小步骤的指令。一板一眼,一次一点点,这正是机器所需要的,也正是机器的专长。

本书第14章提到,Smalltalk开发环境已含自动化重构工具。我并非Smalltalk guy,我没有用过这些工具。基于技术的飞快滚动(或我个人的孤陋寡闻),或许如今你已经可以在Java, C++等面向对象编程环境中找到这一类自动化重构工具。

软件技术圈内,重构(refactoring)常常被拿来与设计模式(design patterns)并论。书籍市场上,《Refactoring》也与《Design Patterns》齐名。GoF曾经说『设计模式为重构提供了目标』,但本书作者Martin亦言『本书并没有提供助你完成所有知名模式的重构手法,甚至连 GoF 的23个知名模式都没有能够全部涵盖。』我们可以从这些话中理解技术的方向,以及书籍所反映的局限。我并不完全赞同Martin所言『哪怕你手上有一个糟糕的设计或甚至一团混乱,你也可以藉由重构将它加工成设计良好的程序代码。』但我十分同意Martin说『你会发现所谓设计不再是一切动作的前提,而是在整个开发过程中逐渐浮现出来。』我比较担心,阅历不足的程序员在读过本书后可能发酵出「先动手再说,死活可重构」的心态,轻忽了事前优秀设计的重要性。任何技术上的说法都必须有基本假设;虽然重构(或更向上说XP,eXtreme Programming)的精神的确是「不妨先动手」,但若草率行事,代价还是很高的。重型开发和轻型开发各有所长,各有应用,世间并无万应灵药,任何东西都不能极端。过犹不及,皆不可取!

在侯捷老师译序中不仅把“废话太多”的原因解释得清清楚楚了,而且顺便解释了《重构》与《设计模式》的关系,最后还告诫我们必须牢记“任何技术上的说法都必须有基本假设”(即应用的背景、上下文,Context)。
(只可惜再版的《重构》中没有了这篇精彩译序,有兴趣的读者不妨读一读繁体版原文。)

正如侯捷老师所说,世间并无万应灵药,《重构》无法解决所有问题。

  • 例如,评论中有人写道“你怎么知道你的重构是安全的?Fowler等人给出的答案是单元测试(Unit testing)。”,或许有人会联想起“单元测试之争”,没错,单元测试不是银弹,它甚至无法保证在我们可预见的情况下是安全的,因此单元测试也有出错的可能,所以才需要结对编程(一人编码,一人旁观,累了就互换角色)来辅助降低出错的可能性。
  • 又如“如何将重构融入不同的软件开发过程”的问题,正如在《软件之道:软件开发争议问题剖析》一书作者所反思的那样:“可复制性已被证明是一个很难捉摸的目标。”,可见那位读者的问题已经超出了《重构》的范围,而且很可能连Martin Fowler本人也给不出答案,因为《重构》产生的背景是极限编程和敏捷思想,至于如何将《重构》移植到其他软件开发过程之中则是个全新的未知领域。
  • 再如有人提出重构不适用于“高度耦合的解析代码(parsing code)”,确实有些重构方法的改进目标是面向对象代码,不过也许多“微不足道”的重构代码是为了提高代码的可读性,以便将来更易维护和扩展,从这个意义上说,《重构》不仅适用于面向对象编程,也适用于面向过程编程。《重构》是藏有72般武器的“宝箱”,程序员要在开发过程中自行挑选“称手的兵刃”。
  • 如最后那位差评读者写道“尽管给出了许多益处,但是重构也给出了一些问题。”,即“在团队协作过程中,即便是改变方法名都是非常困难的,因为改名经常会导致源码中出现冲突。”,然而此问题在今天看来已不算什么问题了,因为先进的版本管理工具和协同开发工具会搞定这一切。

在我个人看来,《重构》不仅有助于改善既有代码质量,而且它还在潜移默化地“重构”着程序员的设计思想和行为习惯 :D

欢迎大家积极分享,各抒己见!