在什么时候重构变得不值得呢?

时间:2009-03-05 16:46:32

标签: refactoring scalability maintainability rebuild

假设你有一个程序当前按照预期的方式运行。该应用程序背后的代码非常糟糕,占用大量内存,不可扩展,并且需要进行大量重写才能实现功能上的任何更改。

在什么时候重构变得不那么符合逻辑,那么总重建?

13 个答案:

答案 0 :(得分:10)

乔尔写了一篇关于这个话题的好文章:

Things You Should Never Do, Part 1

我从中得到的关键教训是,尽管旧代码很糟糕,会伤害你的眼睛和你的美感,很有可能很多代码都是修补无证错误和问题。也就是说,它嵌入了很多领域知识,你很难或不可能复制它。你会不断地打击遗漏的错误。

我发现一本非常有用的书是Michael C. Feathers的Working Effectively With Legacy Code。它提供了接近甚至真正丑陋的遗留代码的策略和方法。

答案 1 :(得分:6)

答案 2 :(得分:6)

重构重建的一个好处是,如果您可以逐步进行重构,即以增量方式进行重构,则可以在整个系统的上下文中测试增量,从而加快开发和调试。

旧的和部署的代码,即使在丑陋和缓慢的情况下,也具有彻底测试的好处,如果从头开始,这种好处就会丢失。

渐进式重构方法还有助于确保始终有可用的产品(并且不断改进)。

网上有一篇关于how Netscape 6 was written from scratch and it was business-wise a bad idea的好文章。

答案 3 :(得分:3)

嗯,最简单的答案是,如果重构需要的时间比重建时间长,那么你应该重建。

如果这是一个个人项目,那么你可能还是想重建它,因为你可能从头开始学习比从重构那里学到的更多,这是个人项目的一个重要目标。

然而,在专业的时间有限的环境中,从长远来看,你应该随时花费最少的钱(相同的收益),这意味着选择花费更少的时间。

当然,它可能比这复杂一点。如果其他人在重构过程中可以处理功能,那么这可能是让每个人都等待构建全新版本的更好选择。在这种情况下,重建可能花费的时间少于 重构所需的时间,但您需要将整个项目和项目的所有贡献者都考虑在内。

答案 4 :(得分:1)

当你花费更多时间进行重构而不是实际编写代码时。

答案 5 :(得分:1)

软件没有做它应该做的事情。当且仅当功能“按预期”时,重构(更改代码而不更改功能)才有意义。

答案 6 :(得分:1)

我过去曾使用过这类应用程序。我发现的最好的方法是逐步的:当您处理代码时,找到多次完成的事情,将它们组合在一起。保留一个笔记本(你知道,一个真正的笔记本,一支纸笔,一支铅笔或一支笔),以便你可以标记你的进度。将其与VCS结合使用,而不是与VCS结合使用。笔记本可用于概述您在重构过程中创建的新功能,VCS当然会填充空白以获取详细信息。

随着时间的推移,您将把大量代码整合到更合适的位置。这段时间内的代码重复几乎是不可能的,所以尽可能做到最好,直到你已经达到真正开始重构过程的程度,审核整个过程代码库并作为一个整体进行处理。

如果你没有足够的时间进行这个过程(这需要很长时间),那么使用测试优先方法从头开始重写可能会更好。

答案 7 :(得分:1)

如果你有足够的时间来完全重建应用程序,不需要逐步改进功能,并且不希望保留任何现有代码,那么重写肯定是一个可行的选择。另一方面,您可以使用重构来执行增量重写,方法是使用更好的写入和更高效的等效函数来缓慢替换现有函数。

答案 8 :(得分:1)

如果应用程序非常小,那么您可以从头开始重写它。如果应用程序很大,永远不要这样做。逐步重写,一步一步验证你没有破坏任何东西。

应用程序是规范。如果你从头开始重写它,你很可能遇到很多阴险的错误,因为“没有人知道对这个函数的调用应该在那个非常具体的情况下返回3”(未记录的行为......)。

从头开始重写总是更有趣,所以你的大脑可能会诱使你认为这是正确的选择。小心,很可能不是。

答案 9 :(得分:1)

Uncle Bob weighs in包含以下内容:

  

什么时候重新设计正确的策略?

     

我很高兴你问这个问题。这是答案。的从不。

     

看,你弄得一团糟,现在把它弄干净了。

答案 10 :(得分:0)

一种选择是编写单元测试以覆盖现有应用程序,然后开始一点一点地重构它,使用单元测试确保一切都像以前一样工作。

在一个理想的世界中,你已经对该程序进行了单元测试,但考虑到你对应用程序质量的评论,我猜你不会...

答案 11 :(得分:0)

没有文档,没有原创作者,没有测试用例,以及一堆剩余的错误。

答案 12 :(得分:0)

当我继承的代码真的很糟糕的时候,我没有太多运气。从理论上讲,小增量方法听起来不错,但实际上它最终得到的是一个更好但设计仍然很差的应用程序,每个人都认为现在是你的设计。当事情破裂时,人们不再认为这是因为之前的代码,它现在成为你的错。因此,我不会使用重新设计,重构或其他暗示经理类型的其他任何内容,除非我真的按照自己的方式去做。否则,即使你已经修复了几十个问题,任何仍然存在的问题(但未被发现)现在都将归因于你的返工。请放心,如果代码不好,那么您的修补程序将发现更多的错误,这些错误之前被忽略,因为代码开始时非常糟糕。

如果您真的知道如何开发软件系统,那么我会重新设计整个系统。如果你真的不知道如何设计GOOD软件,那么我会坚持使用小的增量更改,否则最终会得到一个与原始代码一样糟糕的代码库。

重新设计时经常犯的一个错误是人们忽略了原始代码库。但是,重新设计并不一定意味着完全忽略旧代码。旧代码仍然必须执行新代码必须执行的操作,因此在许多情况下,您需要的步骤已经在旧代码中。复制和粘贴然后在重新设计系统时调整工作奇迹。我发现在许多情况下,重新设计和重写应用程序并从原始代码中窃取代码段比小增量更改更快,更可靠。