💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
### 为何重构 我不想把重构说成治百病的万灵丹,它绝对不是所谓的「银弹」[1]。不过它的确很有价值,虽不是一颗银子弹却是一把「银钳子」,可以帮助你始终良好地控制自己的代码。重构是个工具,它可以(并且应该)为了以下数个目的而被运用。 [1]译注:「银弹」(silver bullet)是美国家喻户晓的比喻。美国民间流传月圆之夜狼人 出没,只有以纯银子弹射穿狼人心脏,才能制服狼人。 **「重构」改进软件设计** 如果没有重构,程序的设计会逐渐腐败变质。当人们只为短期目的,或是在完全理解整体设计之前,就贸然修改代码,程序将逐渐失去自己的结构,程序员愈来愈难通过阅读源码而理解原本设计。重构很像是在整理代码,你所做的就是让所有东西回到应该的位置上。代码结构的流失是累积性的。愈难看出代码所代表的设计意涵,就愈难保护其中设计,于是该设计就腐败得愈快。经常性的重构可以帮助代码维持自己该有的形态。 同样完成一件事,设计不良的程序往往需要更多代码,这常常是因为代码在不同的地方使用完全相同的语句做同样的事。因此改进设计的一个重要方向就是消除重复代码(Duplicate Code)。这个动作的重要性着眼于未来。代码数量减少并不会使系统运行更快,因为这对程序的运行轨迹几乎没有任何明显影响。然而代码数量减少将使未来可能的程序修改动作容易得多。代码愈多,正确的修改就愈困难,因为有更多代码需要理解。你在这儿做了点修改,系统却不如预期那样工作,因为你未曾修改另一处——那儿的代码做着几乎完全一样的事情,只是所处环境略有不同。 如果消除重复代码,你就可以确定代码将所有事物和行为都只表述一次,惟一一次,这正是优秀设计的根本。 **「重构」使软件更易被理解** 从许多角度来说,所谓程序设计,便是与计算机交谈。你编写代码告诉计算机做什么事,它的响应则是精确按照你的指示行动。你得及时填补「想要它做什么」和「告 诉它做什么」之间的缝隙。这种编程模式的核心就是「准确说出吾人所欲」。除了计算机外,你的源码还有其他读者:数个月之后可能会有另一位程序员尝试读懂你的代码并做一些修改。我们很容易忘记这第二位读者,但他才是最重要的。计算机是否多花了数个钟头进行编译,又有什么关系呢?如果一个程序员花费一周时间来修改某段代码,那才关系重大——如果他理解你的代码,这个修改原本只需一小时。 问题在于,当你努力让程序运转的时候,你不会想到未来出现的那个开发者。是的,是应该改变一下我们的开发节奏,对代码做适当修改,让代码变得更易理解。重构可以帮助我们让代码更易读。一开始进行重构时,你的代码可以正常运行,但结构不够理想。在重构上花一点点时间,就可以让代码更好地表达自己的用途。这种编程模式的核心就是「准确说出你的意思」。 关于这一点,我没必要表现得如此无私。很多时候那个「未来的开发者」就是我自己。此时重构就显得尤其重要了。我是个很懒惰的程序员,我的懒惰表现形式之一就是:总是记不住自己写过的代码。事实上对于任何立可查阅的东西我都故意不去记它,因为我怕把自己的脑袋塞爆。我总是尽量把该记住的东西写进程序里头,这样我就不必记住它了。这么一来我就不必太担心Old Peculier(译注:一种有名的麦芽酒〉[Jackson]杀光我的脑细胞。 这种可理解性还有另一方面的作用。我利用重构来协助我理解不熟悉的代码。当我看到不熟悉的代码,我必须试着理解其用途。我先看两行代码,然后对自己说:『噢, 是的,它做了这些那些……』。有了重构这个强大武器在手,我不会满足于这么一点脑中体会。我会真正动手修改代码,让它更好地反映出我的理解,然后重新执行,看它是否仍然正常运作,以此检验我的理解是否正确。 一开始我所做的重构都像这样停留在细枝末节上。随着代码渐趋简洁,我发现自己可以看到一些以前看不到的设计层面的东西。如果不对代码做这些修改,也许我永远看不见它们,因为我的聪明才智不足以在脑子里把这一切都想像出来。Ralph Johnson把这种「早期重构」描述为「擦掉窗户上的污垢,使你看得更远」。研究代码时我发现,重构把我带到更高的理解层次上。如果没有重构,我达不到这种层次。