10

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

重构在什么时候变得比完全重建更不合逻辑?

4

13 回答 13

10

乔尔就这个话题写了一篇很好的文章:

你不应该做的事情,第 1 部分

我从中得到的关键教训是,虽然旧代码很糟糕,会伤害你的眼睛和审美意识,但很有可能很多代码都在修补未记录的错误和问题。即,它嵌入了很多领域知识,你很难或不可能复制它。您将不断遇到遗漏的错误。

我发现非常有用的一本书是Michael C. Feathers 的《有效使用遗留代码》 。它提供了处理真正丑陋的遗留代码的策略和方法。

于 2009-03-05T17:00:36.300 回答
7

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

旧的和部署的代码,即使是丑陋和缓慢的,也有经过彻底测试的好处,如果你从头开始,这种好处就会失去。

增量重构方法还有助于确保始终有可用的产品可以交付(并且不断改进)。

网上有一篇很好的文章,介绍了 Netscape 6 是如何从头开始编写的,但从商业角度来看,这是一个坏主意

于 2009-03-05T16:53:56.563 回答
3

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

如果它是一个个人项目,那么无论如何您都可能希望重新构建它,因为您可能会从零开始构建而不是从重构中学到更多,这是个人项目的一个重要目标。

但是,在专业的限时环境中,从长远来看,您应该始终选择花费公司最少的钱(同样的回报),这意味着选择花费更少的时间。

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

于 2009-03-05T16:49:48.213 回答
1

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

于 2009-03-05T16:48:04.737 回答
1

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

于 2009-03-05T16:48:49.697 回答
1

我过去曾使用过此类应用程序。我发现最好的方法是循序渐进的:当你编写代码时,找到多次完成的事情,将它们组合成函数。保留一个笔记本(你知道,一个真实的,有纸,铅笔或钢笔),这样你就可以标记你的进步。将它与您的 VCS 结合使用,而不是代替它。该笔记本可用于提供您在重构过程中创建的新功能的概述,VCS 当然会填补空白以获取详细信息。

随着时间的推移,您会将大量代码合并到更合适的位置。在这段时间内重复代码几乎是不可能的,所以尽你所能做到最好,直到你可以真正开始重构过程,审核整个代码库并按照整个。

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

于 2009-03-05T16:52:32.167 回答
1

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

于 2009-03-05T16:53:08.203 回答
1

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

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

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

于 2009-03-05T17:00:31.570 回答
0

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

在理想的世界中,您已经对程序进行了单元测试,但是鉴于您对应用程序质量的评论,我猜您不会...

于 2009-03-05T16:48:38.213 回答
0

没有文档,没有原创作者,没有测试用例,还有一堆遗留的错误。

于 2009-03-05T17:31:13.277 回答
0

鲍勃叔叔提出以下意见:

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

我很高兴你问了这个问题。这是答案。绝不。

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

于 2009-03-05T21:19:32.150 回答
0

当我继承的代码真的很糟糕时,我对小的增量更改不太幸运。从理论上讲,小增量方法听起来不错,但在实践中,它最终得到的只是一个更好但设计不佳的应用程序,每个人都认为现在是你的设计。当事情破裂时,人们不再认为是因为以前的代码,现在它变成了你的错。所以,我不会使用重新设计、重构或其他任何暗示经理类型的词除非我真的要按照自己的方式去做,否则您正在按照自己的方式改变事情。否则,即使您可能已经解决了数十个问题,任何仍然存在(但未发现)的问题现在都将归因于您的返工。请放心,如果代码不好,那么您的修复将发现更多以前被忽略的错误,因为代码一开始就很糟糕。

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

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

于 2009-03-05T21:45:29.750 回答