对于重构的重要性相信不需要再强调。在开发的过程中,随着代码的演进,需求的改变我们必须持续不断的对既有代码进行重构:重命名(以更精确地反映元素的职责),提取方法(用更具描述性的名字来归纳一段代码),提取基类(消除重复,提高抽象层次)等。如果我们只是一味的去开发新的代码,而对老代码不闻不问,以为只要它能工作就够了,总有一天我们会在这个上面栽跟头的,设计会慢慢的走向腐化。
好了,本文并不是想强调重构有多重要,因为那不用强调。我想说的是:重构,是小步进行曲。
在阅读Martin Fowler的《重构》时,几次都没有将全书读完,前面几章倒是读的大呼过瘾,不过后面的重构目录让我心生困惑:重构需要这么小的步骤么?连一个重命名都需要这么繁琐的进行。曾几时我还小人的想:老马是不是才思枯竭,没有什么写的了,但又不想出版这么一本薄薄的册子,如是故意弄的这么小步伐,凑篇幅。
不过现在我越来越觉得小步进行的重要性,如果我不能小步的重构一块代码,我甚至都不会去重构它。
在最近的结对编程中,经常碰到这样的场景:
我:这段代码太长了,我们重构一下吧
Partner:好
我:(鼠标键盘一起上了)
Partner:你这样不对(然后抢过键盘)
(实际上我们仅仅是为了想建立一个新类,然后将这个类里的一些方法移动到新的类里,这样原有类的代码就变短了,职责也清晰了,而新类也有很清晰的职责。)
我:(我的做法是,新建一个类,然后将方法copy过去)
Partner:(而搭档的做法是,新建一个类NewClass,然后在原有类里声明一个这个类的字段newClass,然后将要抽离的方法method的方法体再抽取一个方法internalMethod,然后将新方法internalMethod移动到NewClass中,这样method方法就变成newClass.internalMethod,而method的调用者没有任何变化,而在这中间的每一步都运行一下单元测试)
原有类:
//many other code
void method(){
//many code
5: }
//many other code
7: }