无情地重建或建造一个扔掉?

时间:2008-09-17 01:03:41

标签: refactoring

  

在使用新系统概念或新技术的情况下,必须建立一个   系统要扔掉,因为即使是最好的计划也不是那么无所不知   第一次正确行事。因此计划扔掉一个;无论如何,你会的。

     

- Fred Brooks,The Mythical Man-Month [强调我的]

建立一个扔掉。这就是他们告诉我的。然后他们告诉我,我们现在都是agile,所以我们应该Refactor Mercilessly。是什么给了什么?

总是能更好地重构我的方法吗?如果没有,任何人都可以建议一个经验法则来帮助我决定何时坚持下去,何时放弃并重新开始?

14 个答案:

答案 0 :(得分:11)

如果您正在进行测试驱动开发,那么您可以从几乎任何麻烦中重构出来。我毫不费力地改变了主要的设计决策,并拯救了十年前的代码库。

唯一的例外是当您发现您的架构从始至终完全错误时。例如,如果您使用线程编写应用程序,但您发现需要一堆异步状态机。那时,继续扔掉第一稿。

答案 1 :(得分:10)

早点扔掉,稍后重构

对于小型系统来说,扔掉是可以的,但是如果系统的规模很大,那么你就没有资源这么做了。

但是,您可以创建一个小型试点项目,该项目仅实现实际项目的基本功能。经过一些试验和错误以及学习和丢弃的东西,你最终得到了一个坚实的核心和对实际项目更好的理解。然后,通过添加所需的所有功能,让项目的大小增加。但是一旦你到达那里,你就无法丢掉核心。只有重构。

答案 2 :(得分:5)

如果你足够无情,那么重构的最终结果将非常接近你从头开始重建时所获得的结果,但在此过程中你不会被困在一个不工作的系统中。

答案 3 :(得分:4)

“神话人月”的核心要点之一是,软件开发的难点在于弄清楚要说什么,而不是如何说出来。

我最近对此进行解释的方式是,您从初稿中获得的最大价值是您以测试形式收集和保存的要求。如果你小心不要测试那些实际上并不是系统要求的东西,那么可以重构你的方法。

只要您不将自己编码到必须开始抛出测试的陷阱中,就可以在不丢失大量实际工作的情况下丢弃尽可能多的代码。

答案 4 :(得分:3)

我的一般建议是将现有系统从其糟糕的设计重构为具有更好设计的系统。这样可以维护系统并允许它始终部署。如果你从头开始,可能需要一段时间才能部署,或者永远不会。

如果你所说的只是在没有现有系统的情况下编写一些全新的代码,那么通常最好编写一些代码,无论你想要什么,然后抛弃它,因为它从未部署过,重新开始(使用TDD)。

答案 5 :(得分:2)

重构是浪费时间。你只需要从头开始。如果你保持你的设计相当灵活,并且你认识到你还不知道所有的东西,你就不必扔掉任何东西。当然,课程可能会变得多余,但你不会丢掉整个系统。

必须具有灵活的设计才能正确地重构。没有设计或严格的设计意味着你最终会扔掉一些东西 - 要么因为你无法重构,要么因为不断的重构会降低你的代码库的可维护性。很少有人细致而且训练有素,能够完成一系列轻微的重构以保持完整性。除非你有一支全明星队,否则会发生这种退化!

TL; DR:你可以从大多数麻烦中重构出来。但有时,您将无法重构某些设计元素。当发生这种情况时,是时候重新开始了 - 尽管希望你可以重新使用你现有的一些组件。

答案 6 :(得分:2)

不同的情况需要不同的方法。就个人而言,我会尽可能地重构为更好的设计。重构导致比重写更少的错误。

但是,即使你打算扔掉一个,但是编写一堆验收测试仍然是一个好主意,以确保你的第二个版本在正确的轨道上。然后,您可以逐个迁移到下一个版本,同时确保您的功能不会从用户的角度改变。听起来有点像重构,我觉得有点粗鲁。

答案 7 :(得分:2)

在谈论敏捷时,你可以做到这两点,但一般来说,你只会尝试spikes(原型)来尝试特定问题,了解它们并能够做出更好的估算。当你正在编写应用程序时,当你正在做一个简单的尖峰和重构时就扔掉了。

亲切的问候

答案 8 :(得分:1)

当我试图找出新的问题或功能时,我会进行原型设计。之后,我会根据我学到的东西重建它。实际上,这听起来很像重构......什么?也许这是一回事?嗯......

答案 9 :(得分:1)

我认为扔掉一个人有时候是最好的方式,但它可能会受到伤害。我发现效果很好的一件事就是扔掉一个,但选择好你的技术。

例如,我在Ruby on Rails中编写了一个大型代码库,在过去的2 - 3年中,RoR已经取得了很大的进步。我还在架构中做了一些需要修复的决定。所以,我扔了一个,从头开始构建一个新的。但是,我仍然可以使用70-80%左右的旧代码,因为我还在编写Ruby和Rails。

有助于此的主要因素是Rails强制您编写结构良好的代码,并分离业务逻辑和表示层。我第一次没有完美地完成它,但由于一切都相当分离和干,将代码移植到Rails v2.1,重新设计问题区域,并重写一些“问题”功能一直是相当痛苦的经历。

所以,通过从一开始就选择一项伟大的技术,我已经能够扔掉一个,但仍然可以带走70-80%仍旧有效的旧东西。

答案 10 :(得分:1)

在“神话人月”的后期文章中,布鲁克斯警告他发现如果你确实打算扔掉一个人,你最终会扔2个人!

我个人认为这发生在现实生活中;我们将该项目的第1版分配给了一个平庸的程序员,因为“我们计划稍后将它扔掉 - 我们无论如何都会。”我们最终不得不为第2版重写它,但那个也被扔掉了。我从未见过第3版 - 公司倒闭了。

我认为当布鲁克斯说“计划扔掉一个,你会反正”,这更像是声明“剩下的错误数量是'n + 1'。”也就是说,这是一个关于墨菲定律的哈哈认真的陈述,而不是实用的建议。从中汲取的教训是,原型是有价值的,良好的写作是重写的,并且不要害怕放弃不起作用的东西。

然而,它必须归结为一个判断调用,因为正如Joel Spolsky在几篇文章中所讨论的那样,抛弃和重新开始的选择很诱人​​,因为代码比写入更容易编写,写起来更有趣而不是保持,所以即使不是最好的事情,你的自然倾向也将始终重新开始。

答案 11 :(得分:0)

我认为您的版本控制系统在这里发挥着重要作用。如果您使用简单的分支(git,mercurial,这些天)运行分布式版本控制系统,那么您将能够更轻松地进行原型设计,并且重构更轻松,同时仍然拥有有效的工作副本。其他任何事情都需要更多纪律。

答案 12 :(得分:0)

作为该组织的开发经理,我“不被允许”编写生产代码。

我(ab)使用该规则来敲除快速,脏的概念验证代码,解决一个或其他问题,然后我检查它来源控制并指出一个“适当的”开发并说“这是它的完成方式,现在做得恰到好处。“

这就像我们在这里“扔掉一个人”一样接近,而且我可能需要花费几个小时的时间来拼凑起来。花时间处理诸如错误处理,边界检查以及制作好代码的所有其他部分这些都是浪费时间进行这类工作,但这意味着那些获得编写生产代码报酬的人可以花费他们的时间在编写代码审查时,编写生产代码的时间并没有像“它只是原型”这样的借口。

建造一个扔掉的东西经常被用来作为不能正常工作的借口。这意味着你实际上并没有在过程中遇到足够的问题来学习足以让它充分利用任何人的时间。正确地做到这一点,只是扔掉它,更加浪费。

正如几位人士之前所说,任何软件中最重要的特征就是它的出货。考虑到这一点,我建立了“让人们付钱给我”的任何一天,而我在重构方面的无情就是只允许足够的产品才能获得有效且可以合理维护的产品。

答案 13 :(得分:0)

在任何支持分支概念的配置管理系统上构建一个很容易。如果您要将现有系统中的激进设计变更引入现场并且是您薪水的来源;你是一个更好的分支;原型;如果它不起作用就扔掉它。

重构一个大型的传统摇钱树系统往往导致普通的老式黑客攻击。我认为重构听起来比黑客攻击要好得多。