问题 我应该放弃重构这个并计划重写吗? [关闭]


我的任务是保持一个适度大的系统(约60k LOC的非Moose OO Perl)。我开始质疑重构它的智慧,而不是重写它。我知道这个问题已经详细讨论过,但情况异常复杂,并且有几个因素强烈指向相反的方向,因此我的问题。对不起问题的详细程度;在全面了解整个画面时,我尽可能地简洁。

正如系统所代表的那样,它的抽象很难干净地封装任何东西,这可以通过频繁依赖远距离行动,大量使用if / else块以及与手头模块无关的类型对象的深入了解以及依赖性来证明。看起来像社交网络的图表。我觉得这很糟糕,但可以重构。

测试覆盖率不稳定。当然,这是可以修复的,需要在重构之前修复。当然,在这样的系统中,测试需要大量的脚手架,这使得测试覆盖范围的改善变得更加艰巨,但是,这几乎不可能。

所以我打算花很多时间慢慢为混乱带来一些秩序。我认为很难,但可行,系统确实能够很好地用于商业目的,尽管存在所有问题,所以必须做正确的事情。并且“每个人都知道”重写这样的东西是一种灾难。

但最近,我发现系统中一些最重要且写得最差的部分已经存在严重的设计错误并且一直存在于数据模式中。整个方法存在重大问题(这是那些已经研究过它的人的共识,而不仅仅是我),并且这方面的解决方案可能构成了该部分代码的一半,尽管它的编写很糟糕,以至于没有希望将它们区分开来。商业逻辑。这段代码对我自己来说太复杂了(我只用了几个月)或者以前的主要维护者(几年)才能完全理解。它的测试覆盖率也不到10%。

没有人相信他们能够完全正确地描述这一部分的成就,更不用说如何。当代码难以理解且其满足的要求未得到充分理解时,获得此部分的良好测试覆盖几乎是不可能的。没有测试覆盖的重构是不对的,在具有这种普遍问题的这种大小,复杂性的系统中也不是远程实用的(并且动态类型化使得无法自动发现变更的影响)。

由于不断变化的业务需求,不能选择保持这个和黑暗的角落不是一个选择。

我能看到的唯一切实可行的方法就是在业务层面重新定义系统需求,并承诺满足该规范,并冒任何人无法预料的破坏风险。我知道这是一个糟糕的策略,但我没有看到替代方案。如果选择这种方式作为前进的道路,那么重构的好处似乎超出了窗口,这使我严重质疑甚至试图重构这一点的优点。

这引出了我的具体问题:在这种情况下重构一个糟糕的策略吗?支持实际经验的答案是非常优选的,因为我认为理论方面在这里和其他地方已经很好地建立。


5523
2018-01-01 00:12


起源

这里的大红旗是......你实际上并不知道代码的作用!当你真正考虑前进之前,你必须达到理解和记录代码的程度吗? - AmbroseChapel
+1:我认为这是一个很好的问题。不知道为什么有人认为它过于本地化,因为这篇文章可以为同一条船上的其他人提供出色的指导。 - Zaid


答案:


去过也做过。我目前维护的遗留代码是几个非CS人员(工程师)的累积工作,他们着手让他们的程序实现所需的功能,而不考虑可维护性,灵活性或可扩展性。

但对我有用的东西可能并不适用于所有人。

在这种情况下,列出所有相关标准并权衡一个选项通常很有帮助。我倾向于问自己以下问题:

  • 您的雇主是否在代码重写/重构中看到了价值?

    做“做正确的事”很容易被贬低,但只有在你的雇主买入时才这样做。

    我的经验  - 如果业务在重写/重构中没有看到价值,那么你真的应该把这个活动放在后面。专注于记录现有代码,并在尝试根据需要编写/修改/测试任何内容之前,更好地了解代码的工作原理。

  • 新的更新/功能请求多久会添加到代码中?

    进行此类活动的次数越多,重构/重写的情况就越强烈。

    我的经验 - 它是 有时 对您使用现有代码的业务更有价值,并以最少的修改应用记录良好的补丁。

  • 代码将需要在n个月后执行函数X.今天有多大能力?

    如果正在进行开发,这是适用的。从长远来看,看看代码需要做什么以及它能够在当前状态下满足这些需求的程度。

    我的经验  - 重构有时不会削减芥末,因为代码的当前状态严重不足

  • 实施所设想的变更需要多长时间?

    估算应包括理解,记录,实施,测试,验证和发布修改所需的时间。

    我的经验  - 它确实需要比最初想象的更长的时间,特别是测试和验证。


4
2018-01-01 12:59



谢谢!这涵盖了很多关于我宁愿避免的“无所事事”选项的好点,但仍然可能是最好的,我认为你列举了一些很好的理由。 - purpleamy
@purpleamy:我不是说什么都不做;记录此代码可能是您可以做的最有价值的事情。 - Zaid
通过“什么都不做”我的意思是不要试图解决它。当然,记录我们可以提供帮助的“尽力而为”的工作,但它不会解决最严重的问题,甚至也不会让我们更接近这样做。最需要记录的部分是完全发现和记录的边界不可行,因此我的困境。 - purpleamy


首先,阅读 本文 为什么不从Joel Spolsky改写。然后我建议专注于编写测试,这将是重写,重构或正常维护所需要的。完成后,重新访问重写/重构问题。


4
2018-01-01 13:39



我已经读过这个并且同意这个原则,这就是为什么我发现重写(或者或多或少地接受它)难以接受的决定。然而,考虑到问题的相互作用,我很怀疑在纯粹的技术解决方案,如重构是一个可行的解决方案。 - purpleamy
+1文章很棒 - dantuch


我目前在一个项目中处于相同的位置,但我在决定如何进行时使用了几个因素;希望这些会有所帮助。

1)我最大的标准是,项目是否已经发布,我们正在维护一个项目,还是我们正在构建一个即将发布的项目?

  • 如果我们要构建一个要发布的项目,我的目标是发布项目,尽管确保它没有任何我们在发布之前无法解决的安全问题。
  • 如果我们正在维护一个项目,我更倾向于在那里获得全新的代码,因为你不会损害你当前的用户群,但你将获得收益。

2)重写需要多长时间?新代码是否可以节省您在维护和未来开发方面的时间?

  • 很多时候,重写需要比重构更长的时间,但最终可能会为您节省大量的维护和开发时间。

3)我遇到了一些过于严重瓶颈而无法重构的软件,只需要重写,这样软件甚至可以正常工作。

通过我正在进行的项目,我决定大力支持或重构,因为我们正处于开发过程中,如果我们不这样做,我们将能够提前至少3-4个月发布项目重写。 我们确实计划在它发布后进行重写,因为这个软件的维护将是一个负担 - 它也没有经过优化或优化,足以处理软件发布几个月后的用户数量,我们给自己几个月的时间来解决任何重大错误,并在软件中添加更多部分,然后我们将开始重写。

所以,希望我的10¢(2¢+通货膨胀)有所帮助。 祝你好运!


2
2018-01-01 03:58