对话马丁·福勒—第一部分:重构
上一篇 / 下一篇 2012-04-01 09:43:40 / 个人分类:杂谈
~ J:`,G1d0 ——引子:中国软件业所缺少的,不是士兵,而是军官,不是新兵训练营,而是黄埔军校。
D x;V#}#^Y|GA0
?L(}'xe0 第一部分:重构
:hqJYs0 第二部分:设计原则与代码所有权51Testing软件测试网,z#Jq
iG
第三部分:进化型设计51Testing软件测试网6a'~s,gQlx[y*fx
第四部分:灵活性与复杂性51Testing软件测试网1]/y_P[$OH w,L.T
第五部分:测试驱动开发51Testing软件测试网7b$c*`EQ,n n1I.o
第六部分:性能与过程调优
第一部分:重构
)]r6DLgD'G051Testing软件测试网2r5Pei(~$ku%B[在过去十年中,马丁·福勒在商业化信息系统开发领域倡导了许多新的软件开发技术。他在许多领域的工作都为世人所瞩目,包括:面向对象的分 析与设计,软件模式,统一建模语言,敏捷软件开发(特别是极限编程),以及重构。著名的出版社艾迪森维斯理(Addison Wesley)曾出版过若干本他的著作,如《分析模式》(1996年10月),《重构》(1999年6月,与肯特·贝克合著),《UML精粹》(1999 年8月,与肯德尔·斯考特合著),《规划极限编程》(2000年10月,与肯特·贝克合著),以及即将出版的《企业级应用架构模式》(2002年11 月)。51Testing软件测试网%?c,fT%}%H-~
51Testing软件测试网)C'ZbT,WeSN?2Q这次采访分为六个部分。福勒谈到了他对许多话题的看法,包括重构,设计,测试,和极限编程。在第一部分,福勒探讨了重构和测试在开发过程中扮演的角色,并描述了重构、设计、以及可靠性之间的相互作用。
-T;L9\O;W-X1jnq0+f*p'j*[*QR(E0 比尔:请给出重构的定义。51Testing软件测试网gKR'C-J:A[N[
51Testing软件测试网-A%XhJe @x[马丁:重构就是对代码本身做出修改,以改善它的内部结构,但又不改变它的外部表现。
9pBX"e]"k0'r'{q5^-X Q |Q0 比尔:如果重构既不添加新的功能也不消除已有的漏洞,那它的商业目的是什么?你是怎么看待重构的?
1T7i$r*vr5bjYo0%t3C ~}9EQQO0 马丁:重构改善了设计。而一个良好的设计,其商业目的何在?我认为,它使你能在未来更容易地对软件作出改动。
*cx6{?po051Testing软件测试网iVKU6qz重构实际上是在说,“来吧,让我们把系统结构重新调整一下,好让将来的任何改动都更容易些。”其潜台词是,如果你不会改动你的系统,那么也 就没有必要做重构,因为不会有任何回报。但如果你将要对你的系统作出改动——不管是消除漏洞也好,还是添加新功能也好——那么,一个好的或更好的系统结 构,会使你在做修改时有所受益。51Testing软件测试网2O1?QG;b+z/KGk
51Testing软件测试网!S6q0\V^_ sK1K重构与团队51Testing软件测试网C9JP4`1U ^(v
n*vs$z`6s0 比尔:一个团队中,各人有各人的编程习惯。我的一个朋友在一家公司做事,公司进了个新人,那个人对于什么是好的命名规则有自 己的一套想法:他喜欢在成员名字的前面加上“m_”前缀、在词与词之间加上下划线,等等。于是他做了一些简单的重构,就像你推荐的那样,但这些重构造成了 一些问题。51Testing软件测试网1`V \9A&T"[
51Testing软件测试网[k+gp*\F比如,由于授权许可的限制,公司的一些代码是保密的,这个新人无权访问。结果他的重构造成了代码不一致,我的朋友不得不修补这个问题。而 当我的朋友需要修补在多个版本中都存在的漏洞时,问题又来了:重构导致了在不同的版本中命名规则是不一样的,这无疑给不同版本的漏洞修补工作增添了难度。 此外,公司里像我朋友那样的旧员工,已经习惯了旧的命名规则。有一次,我的朋友怎么也找不到一个方法函数,因为它的名字被改了。诸如此类的问题,都是因为 那个新人所做的重构。
,GU.L7M |"R%E4C[#o0w.]uJz9JE1I0 那么,在一个团队里,应该由谁来决定命名规则?又应该由谁来决定何时以及如何做重构?
#rYI*oVH&u051Testing软件测试网4K/v)R2X~Jt q马丁:重构并非让你变态地去重命名一大堆东西,而理由仅仅是你觉得那样好。重构必须要有收益。假设你在做重命名,那么你应 该查找那些名字和意义不符的方法,并且其他使用该方法的人也觉得应该改名才行。说到命名规则,一个团队必须要有一个都能接受的命名规则。如果你是新加入 的,那你必须了解这套命名规则。假设我作为一个咨询师进入团队,那我不会把我的命名规则强加给团队。我会询问团队的命名规则是什么,熟悉它们,使用它们。 当然,从另一方面说,我坚决反对像“x374”这样的命名,因为它不能表达任何意义。
X~jI$i&{O#o4R051Testing软件测试网s|"T&?0k9j:D&v^至于说保密的代码与其他部分代码不一致的问题,这正说明了他们的测试不是很严格。测试对于重构来说,是非常重要的支撑。
\#x~k~g:mHr051Testing软件测试网S|4r4l"ANy4{重构与测试51Testing软件测试网4rNg w$b8hg+X
x%vq*v.H0bm-ac0 比尔:你在《重构》这本书里写道:“如果你打算重构,那么最基本的前提是有完善的测试。”这是不是说,如果没有测试,就不要重构?51Testing软件测试网y6\9`wx"Zs
51Testing软件测试网D{8p]2D f [马丁:没有测试支撑的重构,就如同不系安全带走钢丝。如果你很擅长走钢丝,而且钢丝又不是悬得很高的话,那不妨试试。但如果你从没走过钢丝,而钢丝又是悬在尼亚加拉瀑布上空,那你最好还是有个保靠的安全带。51Testing软件测试网%V!{LWdJ+cP
51Testing软件测试网J{!O/L1@K5E0M!w比尔:如果你目前没有任何测试,那么还有必要追加测试么?51Testing软件测试网-]3I V vHUkQtO
&v(D_3UyV6JB:A0 马丁:还是那句话,代码的一致性可能会因为某人的修改而被破坏,你绝对不希望会有这样的“惊喜”。而类似JUnit的测试的最大好处就是让你能通过运行它们看看是否有什么东西被破坏了。如果你不打算碰你的代码,那当然平安无事;但只要你加新的功能或是修补漏洞,那么你 就有可能破坏某些东西。你的测试越完善,你对能做的改动就越有信心。最终,你能实现比较高的可靠度。51Testing软件测试网+gJ$^t-`RKaC
51Testing软件测试网 ebp*@!H,R)sR以测试为基础的可靠性是极限编程中不大被人们注意的要点之一。人们在谈论极限编程的时候,谈得最多的是它的快速反应力以及轻量化的开发过 程,但往往不提可靠性。而我听到越来越多的故事,都表明极限编程有非常高的可靠性。两周前,我跟以前在 C3 项目的老同事里奇(Rich Garzaniti)聊了聊。克莱斯勒的 C3 项目通常被认为是极限编程的摇篮。在那里,肯特第一次把各种实践有机地结合在一起。里奇谈到了他借助极限编程以及测试和重构所开发的项目。整个系统彻底贯 彻了极限编程的精要。今年到目前为止,他只发现了一处漏洞。51Testing软件测试网)C6Lgq3Ot
_Z[` Em#?0 测试与效率
B$oC6R"],mj J0jJ5q+VZz9f"j0 比尔:在《重构》这本书中,你写道:“作为一个程序员,我写测试是为了提高了自己的工作效率。”那么,测试是否能提高鲁棒性、质量和可靠性呢?
X#v*}5D\)FS;Z0U#hlU,Ep|7t0 马丁:会的,这些都是测试带来的好处。我认为,程序中的缺陷影响了我们的效率,因为我们不得不花时间去修正它们。如果我能 减少一个缺陷,我的效率就得到了提高。至于说我得到了更鲁棒、更可靠的软件,这都是很有价值的副产品。最基本的一点,还是在于我能节省下跟踪和修补漏洞的 时间,从而编写出更多的功能。51Testing软件测试网S~B"b8MWovs
马丁:我能在一天之内就把时间补回来,因为花在跟踪调试上的时间大大减少了。花在测试上的成本很快就能收回。随之而来的还有其它好处。
f4W!Ar)o*]\0klk,~[!K0 比尔:假如一段代码根本没有测试,那么写测试的成本还能很快收回么?
5EA~4{`t'H08GY tr;xE;w|0 马丁:这种情况需要较长的时间。我不建议你花上整整两个月的时间,就是用来写测试。但我认为,通过添加一些测试,你能很快 获得回报,因为你开始发现问题了。如果你把测试集中在你需要做改动的代码部分,那么当你犯错误的时候,测试会告知你这些错误。显然,全面综合的测试会使你 受益最大;但是,就算只写几个测试,你也会从中受益。51Testing软件测试网y;hj,DU'E B LE
51Testing软件测试网*G pL*v}^#A重构与效率
dGi}}l3^0.qGV e[i0 比尔:你说过单元测试可以帮助你提高效率,你还说过重构的好处之一就是能够更快地编程。那么,重构是如何帮助你提高编程速度的呢?51Testing软件测试网.ga+IMn?gT
51Testing软件测试网f!S!R+O S%lfn马丁:因为一个设计良好的程序,修改起来会更容易。程序的设计越好,修改起来就越容易,从而提高了效率。
9l&O`!SUo,kF!^ |051Testing软件测试网H?;aiO2{a重构与性能优化51Testing软件测试网p,k1O/Se%P8G1V l
51Testing软件测试网2R0J9V OZfX)U比尔:你在书里写道,你之所以做重构,并不是出于好玩,而是因为“有些与程序有关的事情,如果不做重构,就无法做到;只有做了重构,才能办到。”那么,你所指的这些事情,除了对程序进行改动,还有哪些事情呢?
8l2j#]!UB1rF%r$@mT051Testing软件测试网)cVTLH.nbT马丁:对程序进行改动是主要的动因。我们不得不经常对软件作出一些改动——只要这个软件还在使用。重构是用来改善设计的。 我们需要一个好的设计以使任何改动都更容易些。重构跟性能优化有些类似,都是在行为不变性(behavior-preserving)前提下的改进。不 过,性能优化的步骤有异于重构,整个过程也有所不同,因为性能优化的驱动要素是性能分析(profiling)。51Testing软件测试网-gQ9C O#B"@
ql7WS^+X'h0 比尔:也就是说,重构所作的改动,不会增加或改变功能,而是为了程序更清晰,这样,将来就可以容易地做出改动。而性能调优的相似之处在于,其所作的改动除了缩短执行时间以外,也不会改变程序的功能。51Testing软件测试网{ i0z0VQ!U
51Testing软件测试网DKdGLT马丁:对。它们有相似之处。不过,我一般还是把它们看成是两个很不一样的概念。
7qv,JG"[J$cQ'V ]&l0S:{9Q&K5jlK0 重构与设计
~.@#vP5II?051Testing软件测试网9bCT#r&G