在敏捷印度 2012 的一次研讨会上, Daniel Brolund 介绍了 Mikado 方法。此方法主张敏捷团队在面临低质的遗留代码时,采用简单的方法,分成小部分逐步完成重构。
通常,当你想在遗留应用程序中做个简单的改动时,经常会有某些事情出错而使这个改动无法执行——如编译出错、验收测试失败(如果有验收测试!)等。当你修复这些问题后,更多的问题又出现了——直到看上去事情全都失控,你都恨不得来重写这个系统了。
Mikado 方法提出了简单的解决方案。当你进行重构时,一旦发现某些依赖的部分出错了,则画一张图表来表示这些错误,并标明真正去修复错误之前,需要先做什么事情。然后还原你的改动,开始观察那张依赖图中的某个叶子结点。修复那个错误,看它是否会引起更多的问题——如果不会,重复这个过程——继续对剩余部分进行重构并在图中画出更多的叶子、还原你的改动,并再从某个叶子结点开始修复工作。
每当还原代码时,你可能觉得自己又回到了原点,而实际上并没有——比起刚开始,你已经掌握了更多的信息。而且,你也主要是在编译能通过(并且测试通过!)的代码上做修改,而不是大量无法编译的代码, 所以也有可能可以使用 IDE 重构工具。每当一个叶子结点上的问题都修复完了、且不再引起更多错误时,就可以签入代码,在依赖图上把这个叶子结点标记为绿色;当某个结点上的所有叶子结点都是绿色了,你就可以以那个结点为基准开始工作,重复上述的过程,直到完成所有原定的重构工作。这意味着代码是以很小的增量逐渐签入的,且可以直接在主干代码上工作(而不用为此再打分支)。
对于重构大型应用系统,似乎这个图表会变得太庞大且难以控制,但是 Daniel 说通常并不是这样的——依赖图的规模与代码的规模通常并不直接成比例。依赖图的主要目的是清楚地记录每一步重构开始时的目标和范围,以便让自己只朝着这个目标工作,而不是试图一次做太多改动。
Daniel 用一个简单的 Java 程序演示了这个方法(这个程序需要重构以使它能支持多种多样的客户)。在随后一场简单的交流会上,与会者也按照此方法顺利完成了重构。你可以从 Github 上下载这个练习的主要内容,也可以下载这本电子书。你还可以阅读InfoQ 上更早的一篇文章《如何进行大规模重构》了解更多。
评论