假设您有一个项目(在您看来)编写得很好,模块化,等等,并且您希望保留它的大部分功能。然而,这个项目的一个重要部分没有很好的设计,而且很难用小的改动来修复。修复它的唯一方法是删除大量代码;它并不是那么糟糕,您需要(或应该)从头开始,但它非常普遍。
假设代码大约是20,000行非空格、非单一的大括号、不注释的Java、C++、C#、PHP或Ruby代码。您估计大约2000-3000行需要抛出或更改。在类似于Java或C#的情况下,您的包/名称空间可能会完全从头开始重写,而且对这些类的许多引用都会发生变化。
下面是具有挑战性的部分:需要更改的代码是系统中的粘合剂。这里有一张非常简单的图片,总结了这个问题:
这就是我所处的情况,导致了这个问题:当我在提交之间等待太久时,我该怎么办?
正如您所看到的,不仅仅是代码的各个部分在执行内部处理,还包括与系统其他部分通信的部分。API和内部数据结构都是不够的。试图使这两组API都可以用于增量更改,这将是令人遗憾的冗余。
当然,我在做任何事情之前都做了分支,但是我所做的每一次改变都产生了一个根本不起作用的产品。在许多情况下,我创建了编译错误。这导致我不断推迟提交,因为我想“是的,我把这些片段连接起来,但是我仍然需要实现这个新的接口,编写这个基本的功能,等等。”这导致了我没有检查任何东西的罪过,如果我再次陷入这种情况,我宁愿不要重复这个错误。我的所有API都是内部的,除了我必须遵守外部世界和第三方模块的API之外,这一点得到了缓解,但是我对这些部分的包装正在改变。
一个明显的替代解决方案是接受这样一个事实,即每一次更改都会导致整个产品的损坏,但是既然您正在签入一个分支,就可以了。特别是因为我是处理这段代码并使用这些API的唯一开发人员。所以也许这是正确的做法。或者,也许正确的做法是尝试首先将API重构到新的API,而不实际更改功能(如果可能的话),即使某些参数是虚拟的,或者最终会被删除,然后增量的更改就会更自我包含。还是有更好的办法呢?
发布于 2014-02-27 14:14:36
简单地说:不要把海洋煮沸。
换句话说,切断一些小的、可管理的块,而不是一次完成整个任务。在一个分支里。没有定期检查。
我一直喜欢这篇文章发表在Joel on上软件。它给出了非常好的具体例子,说明了可以针对代码库进行的小更改,以使代码逐渐变得更干净。
决定一个概念上相似的更改块,并为此创建一个分支。一个示例可能是将所有SQL代码移动到类中。在该分支中,您的工作流程如下所示:
一旦完成了这些更改,就将其合并到主分支中,并启动一个新的块。
这是假设你有测试。如果没有,您应该在开始之前创建它们(包括单元、回归和集成测试)。再说一遍,不是一次全部。如果您想重构一个没有测试的函数,那么编写测试,重构代码并运行测试,直到测试通过为止。这正是这些测试的目的所在。确保你在利用它们。
发布于 2014-02-27 14:13:50
重要的是要知道您的产品是否已经发布,以及您想要接触的API是否以任何方式公开给单独发布的其他实体(模块、项目、产品、文档等)。如果其中任何一个答案都是“是”,则必须在过渡阶段保持API兼容性。与其取代旧的API,不如扩展它。在第二步中,您可以淘汰旧的API并给受影响的实体一个更新的机会。如果可以验证所有相关实体都已停止使用旧API,则只有这样才能将其从您的侧移除。(即使您没有外部依赖项,它仍然可以帮助您使用相同的方法进行重写)。
尽管如此,进行重大重写的一个好方法是尽可能多地将工作划分为较小的独立步骤。
很容易陷入同时处理多个目的的陷阱,但通常会以这样或那样的方式纠缠您的提交--最好的情况是,您必须跟踪多个分支和进展中的特性,这些特性需要在某个时候合并;最糟糕的情况是,所有新特性都是相互交织开发的,防止您对属于单个特性的提交进行清理,甚至阻止您进行任何提交,因为您始终拥有一半工作或不编译的特性。它还将“帮助”您介绍各种模糊的交互错误,在试图找到引入bug的确切位置时会给您带来很多麻烦。
这在很大程度上是一种心理训练,而且有不止一种方法。您可以从突出新API并记录预期用途和API细节开始。一旦完成,您就有了一个稳定的提交点。然后,您可以着手实现单个特性和单元测试(并且可以在此过程中多次提交)。最后,修改调用新API的模块,并完成所有“胶水”工作。此命令将帮助您在不破坏构建的情况下拥有可以提交的停止点。
再说一次,这只是一种方式,而不是唯一的方法。您的目的是模块化重写和最小化更改之间的交互。
发布于 2014-02-27 14:40:50
我参与过不止一次有针对性的重写。在开始编写更多代码之前,您需要做一些分析:
从所有的原始数据来看,你的最终结果应该是什么样的呢?您需要知道什么时候完成,或者什么时候重写足够好给您一个高质量的产品,而不需要放弃每一行代码。
我可以说,经过我的有针对性的重写经验,很多次,最终的产品是更好和更容易维护,但时间表是最大的问题。如果你有有限的时间来完成这项工作,重写会使你的项目比你最初想象的要晚很多。
https://softwareengineering.stackexchange.com/questions/230666
复制