重构:改善既有代码的设计(第2版)(异步图书) (马丁·福勒(Martin Fowler) [马丁·福勒(Martin Fowler)]) (z-library.sk, 1lib.sk, z-lib.sk)
代码Author:马丁·福勒(Martin Fowler) [马丁·福勒(Martin Fowler)]
本书是经典著作《重构》出版20年后的新版。书中清晰揭示了重构的过程,解释了重构的原理和最佳实践方式,并给出了何时以及何地应该开始挖掘代码以求改善。书中给出了60多个可行的重构,每个重构都介绍了一种经过验证的代码变换手法的动机和技术。本书提出的重构准则将帮助开发人员一次一小步地修改代码,从而减少了开发过程中的风险。 本书适合软件开发人员、项目管理人员等阅读,也可作为高等院校计算机及相关专业师生的参考读物。
Tags
Support Statistics
¥.00 ·
0times
Text Preview (First 20 pages)
Registered users can read the full content for free
Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.
Page
1
(This page has no text content)
Page
2
目 录 版权信息 内容提要 版权声明 对本书的赞誉 重读《重构》,呼唤匠艺(译者序) 译者简介 第1版序 前言 服务与支持 第1章 重构,第一个示例 1.1 起点 1.2 对此起始程序的评价 1.3 重构的第一步 1.4 分解statement函数 1.5 进展:大量嵌套函数 1.6 拆分计算阶段与格式化阶段 1.7 进展:分离到两个文件(和两个阶段) 1.8 按类型重组计算过程 1.9 进展:使用多态计算器来提供数据 1.10 结语 第2章 重构的原则 2.1 何谓重构 2.2 两顶帽子 2.3 为何重构 2.4 何时重构 2.5 重构的挑战 2.6 重构、架构和YAGNI
Page
3
2.7 重构与软件开发过程 2.8 重构与性能 2.9 重构起源何处 2.10 自动化重构 2.11 延展阅读 第3章 代码的坏味道 3.1 神秘命名(Mysterious Name) 3.2 重复代码(Duplicated Code) 3.3 过长函数(Long Function) 3.4 过长参数列表(Long Parameter List) 3.5 全局数据(Global Data) 3.6 可变数据(Mutable Data) 3.7 发散式变化(Divergent Change) 3.8 霰弹式修改(Shotgun Surgery) 3.9 依恋情结(Feature Envy) 3.10 数据泥团(Data Clumps) 3.11 基本类型偏执(Primitive Obsession) 3.12 重复的switch (Repeated Switches) 3.13 循环语句(Loops) 3.14 冗赘的元素(Lazy Element) 3.15 夸夸其谈通用性(Speculative Generality) 3.16 临时字段(Temporary Field) 3.17 过长的消息链(Message Chains) 3.18 中间人(Middle Man) 3.19 内幕交易(Insider Trading) 3.20 过大的类(Large Class) 3.21 异曲同工的类(Alternative Classes with Different Interfaces) 3.22 纯数据类(Data Class) 3.23 被拒绝的遗赠(Refused Bequest) 3.24 注释(Comments) 第4章 构筑测试体系 4.1 自测试代码的价值 4.2 待测试的示例代码 4.3 第一个测试 4.4 再添加一个测试 4.5 修改测试夹具 4.6 探测边界条件 4.7 测试远不止如此
Page
4
第5章 介绍重构名录 5.1 重构的记录格式 5.2 挑选重构的依据 第6章 第一组重构 6.1 提炼函数(Extract Function) 6.2 内联函数(Inline Function) 6.3 提炼变量(Extract Variable) 6.4 内联变量(Inline Variable) 6.5 改变函数声明(Change Function Declaration) 6.6 封装变量(Encapsulate Variable) 6.7 变量改名(Rename Variable) 6.8 引入参数对象(Introduce Parameter Object) 6.9 函数组合成类(Combine Functions into Class) 6.10 函数组合成变换(Combine Functions into Transform) 6.11 拆分阶段(Split Phase) 第7章 封装 7.1 封装记录(Encapsulate Record) 7.2 封装集合(Encapsulate Collection) 7.3 以对象取代基本类型(Replace Primitive with Object) 7.4 以查询取代临时变量(Replace Temp with Query) 7.5 提炼类(Extract Class) 7.6 内联类(Inline Class) 7.7 隐藏委托关系(Hide Delegate) 7.8 移除中间人(Remove Middle Man) 7.9 替换算法(Substitute Algorithm) 第8章 搬移特性 8.1 搬移函数(Move Function) 8.2 搬移字段(Move Field) 8.3 搬移语句到函数(Move Statements into Function) 8.4 搬移语句到调用者(Move Statements to Callers) 8.5 以函数调用取代内联代码(Replace Inline Code with Function Call) 8.6 移动语句(Slide Statements) 8.7 拆分循环(Split Loop) 8.8 以管道取代循环(Replace Loop with Pipeline) 8.9 移除死代码(Remove Dead Code) 第9章 重新组织数据
Page
5
9.1 拆分变量(Split Variable) 9.2 字段改名(Rename Field) 9.3 以查询取代派生变量(Replace Derived Variable with Query) 9.4 将引用对象改为值对象(Change Reference to Value) 9.5 将值对象改为引用对象(Change Value to Reference) 第10章 简化条件逻辑 10.1 分解条件表达式(Decompose Conditional) 10.2 合并条件表达式(Consolidate Conditional Expression) 10.3 以卫语句取代嵌套条件表达式(Replace Nested Conditional with Guard Clauses) 10.4 以多态取代条件表达式(Replace Conditional with Polymorphism) 10.5 引入特例(Introduce Special Case) 10.6 引入断言(Introduce Assertion) 第11章 重构API 11.1 将查询函数和修改函数分离(Separate Query from Modifier) 11.2 函数参数化(Parameterize Function) 11.3 移除标记参数(Remove Flag Argument) 11.4 保持对象完整(Preserve Whole Object) 11.5 以查询取代参数(Replace Parameter with Query) 11.6 以参数取代查询(Replace Query with Parameter) 11.7 移除设值函数(Remove Setting Method) 11.8 以工厂函数取代构造函数(Replace Constructor with Factory Function) 11.9 以命令取代函数(Replace Function with Command) 11.10 以函数取代命令(Replace Command with Function) 第12章 处理继承关系 12.1 函数上移(Pull Up Method) 12.2 字段上移(Pull Up Field) 12.3 构造函数本体上移(Pull Up Constructor Body) 12.4 函数下移(Push Down Method) 12.5 字段下移(Push Down Field) 12.6 以子类取代类型码(Replace Type Code with Subclasses) 12.7 移除子类(Remove Subclass) 12.8 提炼超类(Extract Superclass) 12.9 折叠继承体系(Collapse Hierarchy) 12.10 以委托取代子类(Replace Subclass with Delegate) 12.11 以委托取代超类(Replace Superclass with Delegate)
Page
6
参考文献 重构列表 坏味道与重构手法速查表
Page
7
版权信息 书名:重构:改善既有代码的设计(第2版) ISBN:978-7-115-50865-2 本书由人民邮电出版社发行数字版。版权所有,侵权必究。 您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复 制和传播本书内容。 我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。 如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权 措施,并可能追究法律责任。 著 [美] 马丁•福勒(Martin Fowler) 译 熊 节 林从羽 责任编辑 人民邮电出版社出版发行 北京市丰台区成寿寺路11号 邮编 100164 电子邮件 315@ptpress.com.cn 网址 http://www.ptpress.com.cn 读者服务热线:(010)81055410 反盗版热线:(010)81055315
Page
8
内容提要 本书是经典著作《重构》出版20年后的新版。书中清晰揭示了重构的过程, 解释了重构的原理和最佳实践方式,并给出了何时以及何地应该开始挖掘代码以 求改善。书中给出了60多个可行的重构,每个重构都介绍了一种经过验证的代码 变换手法的动机和技术。本书提出的重构准则将帮助开发人员一次一小步地修改 代码,从而减少了开发过程中的风险。 本书适合软件开发人员、项目管理人员等阅读,也可作为高等院校计算机及 相关专业师生的参考读物。
Page
9
版权声明 Authorized Translation from the English language edition, entitled REFACTORING: IMPROVING THE DESIGN OF EXISTING CODE, 2nd Edition by FOWLER, MARTIN, published by Pearson Education, Inc, Copyright © 2019 Pearson Education, Inc. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. CHINESE SIMPLIFIED language edition published by POSTS & TELECOM PRESS, Copyright © 2019. 本书中文简体字版由Pearson Education Inc授权人民邮电出版社独家出版。未 经出版者书面许可,不得以任何方式复制或抄袭本书内容。 本书封面贴有Pearson Education(培生教育出版集团)激光防伪标签,无标 签者不得销售。 版权所有,侵权必究。
Page
10
对本书的赞誉 过去20年,《重构》一直是我案头常备的图书。每次重读,仍有感悟。对我 而言,《重构》的意义不只在于指导代码重构,更在于让人从一开始就知道什么 是好的代码,并且尽量写出没有“坏味道”的代码。Martin Fowler这次对本书进行 的重构,体现了近年来编程领域的一些思潮变化。看来,既有设计,永远有改进 空间。 ——韩磊,《代码整洁之道》译者 重构早就成了软件开发从业者本能的一部分,每个IDE都内置了重构功能, 每个程序员都定期重构自己的代码。技能上通常不再是问题,但是相对于当年第 1版的读者,现在的程序员对于重构这个思想从何而来以及各种细节反而更陌 生,这时候就更值得重新读一下这本书了。 ——霍炬,PRESS.one CTO 有人说Martin Fowler改变了人类开发软件的模式,这一点也不过分,从《分 析模式》《UML精粹》《领域特定语言》,到这本《重构》新版可以看得出来, 他的每一本书都是软件开发人员必备的案头读物。此前他参与的“敏捷宣言”,更 是引领了整个行业对敏捷开发的认识,一直到现在。Martin Fowler是我们QCon全 球软件开发大会进入中国时的第一届讲师,也是在那次会议上,他让国内的技术 社区领略了国际领先的开发模式,从此“敏捷”二字开始风行国内IT领域。 今年是QCon进入中国的第十个年头,我特别开心看到Martin Fowler又重写 《重构》这本影响深远的书,他几乎完全替换了书中所引用的模式案例,并且基 于现在用户的习惯,采用了JavaScript语言来做说明语言。数十年来他始终保持对 技术的关注,对创新的热情,乐此不疲,这是Martin最令人敬佩的地方,也是非 常值得我们每一个技术人学习的地方。 ——霍泰稳,极客邦科技、InfoQ中国创始人兼CEO 当今软件开发的速度越来越快,带来的技术债也越来越多,我从CSDN自身 的网站系统开发中充分认识到重构的重要性——如果我们的程序员能理解和掌握 重构的原则和方法,我们的系统就不会有这么多沉重的债务。真正本质的东西是 不变的,《重构》在出版20年后推出了第2版,再次证明:越本质的越长久,也 越重要。衷心期待更多的新一代开发者能从这本书吸收营养,开发出好味道的系 统。
Page
11
——蒋涛,CSDN创始人、董事长 最早看到本书第1版的英文原版并决定引进国内,算起来已经是20年前的事 了。虽然时间是最强大的重构工具,连书里的示例语言都从Java变成JavaScript 了,但书中的理念和实践的价值并没有随时间流逝。这充分证明,即使在日新月 异的IT技术世界里,不变的东西其实还是有的,这种书才是真正的经典,是技术 人员应该优先研读并一读再读的。 ——刘江,美团技术学院院长 “对于软件工程师来说,重构,并不是额外的工作,它就是编码本身。”直到 我读过《重构》,并经过练习,才真正理解到这一点。真希望自己在20多年前写 第一个软件时,就能读到这本书,从而能节省出大量调试或重复研究代码的时 间。20年过去了,《重构》这本书也根据当前软件设计及相关工具的发展进行了 一部分修订,更加贴近当前的软件开发者。希望更多的软件工程师能够应用这一 技术节省出更多的时间。 ——乔梁,腾讯高级管理顾问、《持续交付2.0》作者 重构是一项被低估了的技术能力。说起来,重构就是“不改变外在行为,而 提高代码质量”这么简简单单的一句话,但其带来的影响却非常深远:它使我们 在解决问题时可以放心地“先做对,再做好”——这种思路本身就可以极大地简化 问题;它使我们消除无谓的意气之争——“所谓好,就是更少的坏味道”。我由衷 地认为,切实地读懂了《重构》的程序员,在能力上都会获得一个数量级的提 升。 ——徐昊,ThoughtWorks中国区技术总监 当我还是编程菜鸟,想写出漂亮的代码而不得门道的时候,《重构》这本书 就告诉了我,其实高手的代码也不是一次书就的,只要按这本书里的方法去做, 谁都能把代码写得那么好;当我还是职场新人,没来得及写出太多垃圾代码的时 候,这本书就教会了我,应该去追求编写人能够读懂的而不是仅机器能够读懂的 代码。多年以后的某时某刻,当你编码自信而敏捷,因代码清晰而受人尊重时, 你会庆幸读过这本书,你也会有些遗憾,应该再早一点去读这本书。无论过去了 多少年,这本书,一直值得推荐。 ——阎华,京东7FRESH架构师 在大获成功的《重构》第1版里,Martin Fowler传达的核心理念是:代码会 随时间流逝而烂掉。写得再好的程序代码,若是发布了就一直保持原样,照样会 风化、破碎乃至分崩离析。这是客观规律,避免这种命运的唯一出路是持续重
Page
12
构。要想成为高素质的软件工程师,必须认识这一点。 20年之后,Martin Fowler用现身说法证明,经典的《重构》也会变得不合时 宜,也需要重构。如今,不但讲解语言从Java改成了JavaScript,原来的重构示例 也做了很多调整,新增了15个示例,更重要的是,新版示例不再那么“面向对 象”,应当会收获更广泛的读者群。 软件不死,重构不歇。 ——余晟,《代码整洁之道:程序员的职业素养》译者 随着软件项目日积月累,系统维护成本变得越来越高昂是互联网团队共同面 临的问题。用户在使用互联网系统的过程中,遇到的各类运行错误或者不可访问 故障,以及开发团队面临的历史系统不可维护问题,很多时候是代码初次开发过 程中各种细小的不规范引起的。持续优化已有代码是维护系统生命力最好的方 法。《重构》是我推荐团队必读的技术图书之一。 ——杨卫华(Tim Yang),微博研发副总经理 软件行业已经高速发展数十年,就好似一个崭新的城市,从一个个村屋矮房 到高楼林立。而你的代码库就好比你手下的一个房间、一幢平房、一条街道、一 片社区乃至是一座摩天大楼。作为一本经典的软件开发书,《重构》告诉我们的 不仅仅是如何推倒重建、清理、装修,而是像一个规划师一样从目的、成本、手 段、价值等综合维度来思考重构的意义。在开发业务的同时,《重构》常伴我左 右,警醒我如何写出更有价值的软件。 ——阴明,掘金社区创始人 重构,是一个优秀程序员的基本功,因为没人能保证其代码不随时间腐化, 而重构会让代码重新焕发活力。整个软件行业对重构的认知始于Martin Fowler的 《重构》,这本书让人们知道了“代码的坏味道”,见识到了“小步前行”的威力。 时隔20年,Martin Fowler重新执笔改写《重构》,20年间的思维变迁就体现在这 本书里,在第1版中,我们看到的是当时方兴未艾的面向对象,而第2版则透露出 函数式编程的影响。如果说有什么程序员进阶秘笈,那就是不要错过Martin Fowler的任何一部著作,更何况是已经由时间证明过的重要著作《重构》的新 版! ——郑晔,火币网首席架构师 如果看完本书,就兴冲冲地想要找一些代码来重构,那你可能就陷入某 种“自嗨”之中了。
Page
13
了解本书中列出的那些坏味道,不仅仅可以发现代码中的那些坏味道,更可 以鞭策自己以及整个团队:在一开始的时候,就不写或者少些那种味道很坏的代 码。还应该激励自己,深入地理解架构、理解业务、理解需求,减少因设计失误 而导致徒劳无益地反复重构。 重构也是有成本的,所以应该思考如何降低重构的成本。我推荐每一个程序 员都来学习“重构”这门手艺。因为学习《重构》,是为了减少“重构”! ——庄表伟,开源社理事、执行长,华为云DevCloud高级产品经理
Page
14
重读《重构》,呼唤匠艺(译者序) 2009年,在为《重构》第1版的中译本再版整理译稿时,我已经隐约察觉行 业中对“重构”这个概念的矛盾张力。一方面,在这个“VUCA”(易变、不确定、 复杂、模糊)横行的年代,有能力调整系统的内部结构,使其更具长期生命力, 这是一个令人神往的期许。另一方面,重构的扎实功夫要学起来、做起来,颇不 是件轻松的事,且不说详尽到近乎琐碎的重构手法,光是单元测试一事,怕是已 有九成同行无法企及。结果,“重构”渐渐成了一块漂亮的招牌,大家都愿意挂上 这个名号,可实际上干的却多是“刀劈斧砍”的勾当。 如今又是10年过去,只从国内的情况而论,“重构”概念的表里分离,大有愈 演愈烈之势。随着当年的一线技术人员纷纷走上领导岗位,他们乐于将“重构”这 块漂亮招牌用在更宽泛的环境下,例如系统架构乃至组织结构,都可以“重构”一 下。然而基本功的欠缺,却也一路如影随形。当年在对象中的刀劈斧砍,如今被 照搬到了架构、组织的调整。于是“重构”的痛苦回忆又一遍遍重演,甚而程度更 深、影响更广、为害更烈。 此时转头看Martin Fowler时隔将近廿载后终于付梓的《重构》第2版,我不 禁感叹于他对“微末功夫”的执着。在此书尚未成型之前,我和当时ThoughtWorks 的同事曾有很多猜测,猜Fowler先生是否会在第2版中拔高层次,多谈谈设计乃 至架构级别的重构手法,甚或跟随“敏捷组织”“精益企业”的风潮谈谈组织重构, 也未为不可。孰料成书令我们跌破眼镜,Fowler先生不仅没有拔高,反而把工夫 做得更扎实了。 对比前后两版的重构列表,可以发现:第2版收录的重构手法在用途上更加 内聚,在操作上更加连贯,更重视重构手法之间的组合运用。第1版中占了整章 篇幅的“大型重构”,在第2版中全数删去。一些较为复杂的重构手法,例如复 制“被监视数据”、塑造模板函数等,第2版也不再收录。而第2版中新增的重构手 法,则多是提炼变量、移动语句、拆分循环、拆分变量这样更加细致而微的操 作。这些新增的手法看似简单,但直指大规模遗留代码中最常见的重构难点,正 好补上了第1版中阙漏的细节。这一变化,正反映出Fowler先生对于重构一事一 贯的态度:千里之行积于跬步,越是面对复杂多变的外部环境,越是要做好基本 功、迈出扎实步。 识别坏味道、测试先行、行为保持的变更动作,是重构的基本功。在《重 构》第2版里,重构手法的细节被再度打磨,重构过程比之第1版愈发流畅。细细 品味重构手法中的前后步骤,琢磨作者是如何做到行为保持的,这是能启发读者
Page
15
举一反三的读书法。以保持对象完整重构手法为例,第1版中的做法是在原本函 数上新添参数,而第2版的做法则是先新建一个空函数,在其中做完想要的调整 之后,再整体替换原本函数。两相对比,无疑是新的做法更加可控、出错时测试 失败的范围更小。 无独有偶,我在ThoughtWorks时的同事王健在开展大型的架构重构时,总结 了重构的“十六字心法”,恰与保持对象完整重构手法在第2版中这个新的做法暗 合。这十六字心法如是说: 旧的不变, 新的创建, 一步切换, 旧的再见。 从这个视角品味一个个重构巨细靡遗的做法,读者大概能感受到重构与“刀 劈斧砍”之间最根本的分歧。在很多重构(例如最常用的改变函数声明)的做法 中,Fowler先生会引入“很快就会再次修改甚至删除”的临时元素。假如只看起止 状态,这些变更过程中的临时元素似乎是浪费:为何不直接一步到位改变到完善 的结果状态呢?然而这些临时元素所代表的,是对变更过程(而非只是结果)的 设计。缺乏对过程的精心设计与必要投入,只抱着对结果的美好憧憬提刀上阵, 遇到困难就靠“奋斗精神”和加班解决,这种“刀劈斧砍”不止发生在缺乏审慎的“重 构”现场,又何尝不是我们这个行业的缩影? 是以,重构这门技艺,以及Fowler先生撰写《重构》的态度,代表的是软件 开发的匠艺——对“正确的做事方式”的重视。在一个浮躁之风日盛的行业中,很 多人会强调“只看结果”,轻视做事的过程与方式。然而对于软件开发的专业人士 而言,如果忽视了过程与方式,也就等于放弃了我们自己的立身之本。Fowler先 生近廿载对这本书、对重构手法的精心打磨,给了我们一个榜样:一个对匠艺上 心的专业人士,日积月累对过程与方式的重视,是能有所成就的。 17年前,我以菜鸟之身读到《重构》,深受其中蕴涵的工匠精神感召,在 Fowler先生与侯捷老师的帮助下,完成了本书第1版的翻译工作。如今再译本书 第2版,来自ThoughtWorks的青年才俊林从羽君主动请缨与我搭档合译,我亦将 此视为匠艺传承的一桩美事。新一代程序员中,关注新工具、新框架、新商业模 式者伙矣,关注面向对象、TDD、重构之类基本功者寥寥。林君年纪虽轻,却能 平心静气磨砺技艺,对基本功学而时习,颇有老派工匠之风。当年藉由翻译《重 构》一书,我从Fowler先生、侯捷老师身上学到他们的工匠精神,十余年来时时 践行自勉。如今新一代软件工匠的代表人物林君接手此书,必会令工匠精神传承
Page
16
光大。 据说古时高僧有偈云:“时时勤拂拭,勿使惹尘埃。”代码当如是,专业人士 的技艺亦当如是。与《重构》的诸位读者共勉。 熊节 2019年1月26日于成都
Page
17
译者简介 熊节 在IT行业已经打拼了18年,在金融、零售、政府、电信、制造业等行 业的信息化建设方面有着丰富经验,是中国IT业敏捷浪潮的领军人物。熊节拥有 利物浦大学MBA学位。 林从羽 ThoughtWorks软件开发工程师,曾服务于国内外多家大型企业,致 力于帮助团队更快更好地交付可工作的软件。拥抱敏捷精神,TDD爱好者,纯键 盘工作者。
Page
18
第1版序 “重构”这个概念来自Smalltalk圈子,没多久就进入了其他编程语言阵营之 中。因为重构是框架开发中不可缺少的一部分,所以当框架设计者讨论自己的工 作时,这个术语就诞生了。当他们精炼自己的类继承体系时,当他们叫喊自己可 以拿掉多少多少行代码时,重构的概念慢慢浮出水面。框架设计者知道,这东西 不可能一开始就完全正确,它将随着设计者的经验成长而进化;他们也知道,代 码被阅读和被修改的次数远远多于它被编写的次数。保持代码易读、易修改的关 键,就是重构——对框架而言如此,对一般软件也如此。 好极了,还有什么问题吗?问题很显然:重构有风险。它必须修改正在工作 的程序,这可能引入一些不易察觉的错误。如果重构方式不恰当,可能毁掉你数 天甚至数周的成果。如果重构时不做好准备,不遵守规则,风险就更大。你挖掘 自己的代码,很快发现了一些值得修改的地方,于是你挖得更深。挖得越深,找 到的重构机会就越多,于是你的修改也越多……最后你给自己挖了个大坑,却爬 不出去了。为了避免自掘坟墓,重构必须系统化进行。我和三位合作者在写《设 计模式》一书时曾经提过:设计模式为重构提供了目标。然而“确定目标”只是问 题的一部分而已,改造程序以达到目标,是另一个难题。 Martin Fowler和本书另几位作者清楚地揭示了重构过程,他们为面向对象软 件开发所做的贡献难以估量。本书解释了重构的原理和最佳实践,并指出何时何 地你应该开始挖掘你的代码以求改善。本书的核心是一系列完整的重构方法,其 中每一项都介绍一种经过实践检验的代码变换手法的动机和技术。某些项目 (如“提炼函数”和“搬移字段”)看起来可能很浅显,但不要掉以轻心,因为理解 这类技术正是有条不紊地进行重构的关键。本书所提的这些重构手法将帮助你一 次一小步地修改你的代码,这就降低了设计演进过程中的风险。很快你就会把这 些重构手法及其名称加入自己的开发词典中,并且朗朗上口。 我第一次体验有条不紊的、一次一小步的重构,是某次与Kent Beck在三万英 尺高空的飞行旅途中结对编程。我们运用本书中收录的重构手法,保证每次只走 一步。最后,我对这种实践方式的效果感到十分惊讶。我不但对产生的代码更有 信心,而且开发压力也小了很多。因此,我极力推荐你试试这些重构手法,你和 你的程序都将因此更美好。 ——Erich Gamma Object Technology International, Inc.
Page
19
1999年1月
Page
20
前言 从前,有位咨询顾问造访客户调研其开发项目。该系统的核心是一个类继承 体系,顾问看了开发人员所写的一些代码。他发现整个体系相当凌乱,上层超类 对系统的工作方式做了一些假设,下层子类实现这些假设。但是这些假设并不适 合所有子类,导致覆写(override)工作非常繁重。只要在超类做点修改,就可 以减少许多覆写工作。在另一些地方,超类的某些意图并未被良好理解,因此其 中某些行为在子类内重复出现。还有一些地方,好几个子类做相同的事情,其实 可以把它们搬到继承体系的上层去做。 这位顾问于是建议项目经理看看这些代码,把它们整理一下,但是项目经理 并不热衷于此,毕竟程序看上去还可以运行,而且项目面临很大的进度压力。于 是项目经理说,晚些时候再抽时间做这些整理工作。 顾问也把他的想法告诉了在这个继承体系上工作的程序员,告诉他们可能发 生的事情。程序员都很敏锐,马上就看出问题的严重性。他们知道这并不全是他 们的错,有时候的确需要借助外力才能发现问题。程序员立刻用了一两天的时间 整理好这个继承体系,并删掉了其中一半代码,功能毫发无损。他们对此十分满 意,而且发现在继承体系中加入新的类或使用系统中的其他类都更快、更容易 了。 项目经理并不高兴。进度排得很紧,有许多工作要做。系统必须在几个月之 后发布,而这些程序员却白白耗费了两天时间,做的工作与未来几个月要交付的 大量功能毫不相干。原先的代码运行起来还算正常。的确,新的设计更加“纯 粹”、更加“整洁”。但项目要交付给客户的,是可以有效运行的代码,不是用以 取悦学究的代码。顾问接下来又建议应该在系统的其他核心部分进行这样的整理 工作,这会使整个项目停顿一至两个星期。所有这些工作只是为了让代码看起来 更漂亮,并不能给系统添加任何新功能。 你对这个故事有什么感想?你认为这个顾问的建议(更进一步整理程序)是 对的吗?你会遵循那句古老的工程谚语吗:“如果它还可以运行,就不要动它。” 我必须承认自己有某些偏见,因为我就是那个顾问。6个月之后这个项目宣 告失败,很大的原因是代码太复杂,无法调试,也无法将性能调优到可接受的水 平。 后来,这个项目重新启动,几乎从头开始编写整个系统,Kent Beck受邀做了
Comments 0
Loading comments...
Reply to Comment
Edit Comment