图0:[外文翻译]Martin Fowler:机会主义式的代码重构

贺卓凡译Martin著 ImportSource

从我开始谈论和撰写关于重构专题的一开始,人们就问我如何将重构纳入更广泛的软件开发过程。

重构到底应不应该被当做软件开发生命周期的一个阶段,如果应该,那么要在一个迭代中给重构这个阶段分配多大比例呢?我们又该确定哪些人去做重构任务呢?虽然重构工作可以这样规划,但我还是倾向于重构作为机会主义的活动来开展,就是无论何时何地都需要清理代码,不管是谁。

图1:[外文翻译]Martin Fowler:机会主义式的代码重构

这意味着,在任何时候,有人看到一些不那么清晰工整的代码,他们都应该抓住机会立即修复,或者至少在几分钟之内。这个机会主义重构由Uncle Bob 提出,遵循童子军(boy-scout rule)规则[1] – 总是让代码保持着比你当初发现这个代码时更好的状态。如果团队中的每个人都在这样做,他们每天都会对代码库健康做出小的定期贡献。

这个机会可能来自于各个方面,比如实现一些新功能或修复一个bug的时候。一个机会是“准备阶段的重构”,在你开始实现任务之前,你发现如果这个现有类的API稍微改变的一点的话,这个任务实现起来可能会更加的容易。这时候,你可以先将它重构为应该有的样子,然后再开始添加你的功能。

另一个重构机会是,当你添加功能时,你会发现你添加的一些代码和一些现有代码是重复的,这时候你就可以重构现有代码以使得代码更整洁。这种对代码的持续关注是重要的 – 但是请记住,你应该只重构那些被测试为绿色ok的代码。

你可能会得到一些任务,但是意识到如果与现有类的交互改变了的话,那么会更好。在考虑自己实现之前,请抓住机会去做这样的重构。

有时你会看到一个机会,当你在做别的东西的时候。这时候,为了不打断你目前的做事的思路,你可以把这个问题记录下来,等有时间后再回来做重构。但不要隔得太久,最好是当天,在你完成了正在进行的任务以后就可以回来重构了。

有些人反对这样的重构,因为你把时间花在重构上而不是去研究一个有价值的功能。但是,重构的重点在于使代码更易于使用,从而使得团队更快地增加价值。如果你不花时间去重构,那么代码基础质量会逐渐降低。

但说了这么多,重构还是有一个真正的风险,你可能会掉进一个兔子洞,你修复一件事然后你又发现另一个,再修复,然后又发现另外一个,就这样一直下去,你就深陷一团乱麻了。巧妙的机会主义重构需要很好的判断力,你决定在什么时候哪些地方重构,这个需要很好的判断力。你想让代码比你发现的时候更好,但是它也可以等待作者去重构,使之成为你真正想要看到的方式。如果你总是让事情变得更好一些,那些经常被光顾的地方最后就会产生一个很大的影响 – 这正是清洁代码最有价值的领域。像编程的大多数方面,这个决定和判断力需要深思熟虑。

机会主义重构的一个作用就是它可以触碰到你正在负责的代码的任何一部分。你可能会在一个class里做大部分的工作,但是发现这个类中的问题是出在其他地方的代码中。缺乏本地化,并不应该是阻止你现在做出改变的障碍。这样的情况,常常使得你产生一种侥幸就是改天再改吧- 但这个“改天”往往不会来。

重构确实取决于你是否有一个好的回归测试套件,如果你认为你将要接触的应用程序的那部分的测试比较薄弱的话,那么请谨慎重构。

。在这种情况下,如果你能做到不会在兔子洞里偏离太远,那么投入一两次额外的测试是可以接受的。而且我发现,制造一个故意的错误,看看测试是否能抓住它。通过这样的方式也可以衡量我们的安全网到底是一个什么水平。

我担心任何可能导致机会主义重构产生阻力的开发实践,例如Strong    Code Ownership[2]或使用功能分支(Feature Branch)。这实际上是我使用功能分支的主要关切。当人们正在使用功能分支时,通常情况下,他们不鼓励机会主义重构,因为它使合并变得更加困难[3] – 特别是如果分支活动时间长于几天。

我的感觉是大多数团队没有做足够的重构,所以关注那些妨碍人们重构的任何人事物是非常关键的。去帮助清除那些你感觉会阻止人们做小型重构的障碍,那些你确定只需要花费一两分钟的重构。任何这样的障碍都应该要促进一次沟通和对话,至少有这样的主张。所以,遇到这样的障碍,就立即把它记录下来,然后把这个问题向团队公开。或者至少应该在你的下一个回顾中要去讨论这样的问题。

从一开始,你应该总是把重构作为你不断做的事情,像编写if语句一样,是编写程序的常规部分和不可分割的一部分。然而,对于重构有一个常见的误解,认为重构是需要规划的。

当然了,你是可以制定一个计划,甚至专门腾出一两天的时间来重构你们写了几个月时间的代码。

但是,使用重构比较好的团队是几乎不需要计划重构,而是将重构视为一个不断的小调整流,使项目保持在Design Stamina Hypothesis[4]的快乐曲线上。

注解

1:Boy-Scout Rule:

童子军有一条规则:“让营地比你刚来时更干净。”如果看到地上有垃圾,不管是谁扔的,都要清理。这样你就有意地为下一批来宿营的人改善了环境。事实上,这条规则的最初说法是“让世界比你刚来时更美好”,出自罗伯特·贝登堡,童子军之父。

2:Strong Code Ownership:强大的代码所有权管理。在这种管理下,你无法轻易的触碰到自己代码以外的代码。因为它将代码库分成模块(类,函数,文件),并将每个模块分配给一个开发人员。 开发人员只能对自己拥有的模块进行更改。 如果他们需要对别人的模块进行更改,那么他们需要与模块所有者交谈并让他们进行更改。

3:现代工具对重构有帮助,但这些现代工具有时候也会被语义冲突(Semantic Conflicts)搞晕。

4:Design Stamina Hypothesis:https://martinfowler.com/bliki/DesignStaminaHypothesis.html,该文中提出疑问:Is it worth the effort to design software well?

图2:[外文翻译]Martin Fowler:机会主义式的代码重构

译者说

事实上现存的很多开发方法或管理方法都和机会主义重构是相背离的,然而笔者认为机会主义重构是你的代码通向伟大的必由之路。从此文也使得我们不禁要发问,过分的设计和计划到底合不合理?计划和设计也许能保证你的开发质量趋于稳定,但能不能通向伟大呢?这就像过多的管理审核流程一样,他能确保你的组织运转稳定,但却让你们逐渐远离了新鲜、先进和灵感,最后走向了平庸。

余下全文(1/3)
分享这篇文章:

请关注我们:

发表评论

电子邮件地址不会被公开。 必填项已用*标注