【问题标题】:How to refactor rapidly evolving code?如何重构快速发展的代码?
【发布时间】:2009-02-26 05:02:20
【问题描述】:

我有一些研究代码是真正的老鼠窝,到处都是重复的代码,显然需要重构。然而,代码库正在演变,因为我提出了新的主题变体并将它们融入代码库。我推迟重构这么久的原因是因为我觉得我花了几天时间提出好的抽象,看看哪些设计模式适合哪里,等等,我想尝试一些新的不可预见的想法使我的抽象完全不充分。换句话说,由于代码的发展速度,我真的不知道抽象线属于哪里,即使不乏(近似)重复,而且代码的一般混乱使得向其中添加东西成为现实痛。应对这种情况的一般最佳做法是什么?

【问题讨论】:

    标签: coding-style refactoring code-duplication


    【解决方案1】:

    不要花这么长时间重构!

    当您要更改一段代码时,请考虑重构它以使更改更容易。

    进行更改后,再次重构以清除该更改造成的损害。

    在这两种情况下,尽量缩小重构并快速完成,然后继续。

    您不必始终保持代码的原始状态,但请记住,如果您有良好的代码可以处理(并且如果您有良好的单元测试),那么快速会更容易,当然)。

    【讨论】:

      【解决方案2】:

      测试驱动开发:

      红色、绿色、重构。冲洗,重复。

      由于它是每个周期中的步骤之一,您会注意到通常会发生很多次要重构。应该是这样的。

      【讨论】:

        【解决方案3】:

        你的情况我很熟悉。在进行调查性编码时,您通常不知道“正确”的抽象是什么,正如您所说,它会随着每个新想法而改变。
        其他发帖人建议:

        • 持续的小重构,有助于避免陷入鼠窝的境地
        • 测试驱动开发,有助于找到好的、可重用的抽象。请务必注意,TDD 与其说是测试,不如说是做良好的设计!

        但是,对于调查研究代码还有另一种策略:原型。这似乎是你目前正在做的事情:尽快编码来证明一个概念。这并没有错,但原型应该始终被丢弃。调整它直到您拥有所有必要的输入和知识,然后扔掉 离开代码并重新开始 TDD 和持续重构,以及所有其他“正确地做事”策略。

        不要保留任何代码。不要复制粘贴任何东西。不要回头提及它。用你的新知识重新开始吧。

        【讨论】:

          【解决方案4】:

          一次清理一点代码。总是当你接触一个班级时,尽量让班级保持在你接触它之前的状态("the boy scout rule")。重构最好分小步进行,但要经常进行。

          重命名变量、拆分方法等操作只需几秒钟或几分钟。大型重构,例如拆分或加入类,可能需要一两个小时(并且您以小步骤进行,以便所有测试至少每五分钟通过一次 - 否则您已输入 Refactoring Hell 并且您应该恢复到最后一个已知的工作状态)。如果你需要几天或几周的时间来重构某些东西,那么它就不再是“重构”了——它更像是重写。

          有关此主题的文章: http://blog.objectmentor.com/articles/2007/07/20/whats-your-unit-of-measure

          【讨论】:

            【解决方案5】:

            至少把它放在像 Git 这样的分布式 SCM 中,这样当你破坏某些重构时,你可以分开时间来找到更改之前的提交,并且能够处理更改并将它们提交到分支中而不会干扰与他人一起工作。

            Gits 分支合并非常适合这样的事情,如果 2 个人并行进行了不兼容的更改,您将很容易知道,而不必担心其余代码。

            由于上述原因,我还将在存储库中创建一个单独的分支只是用于重构代码,并定期更新它。这样,其他人不仅不会干扰您的进度,而且他们可以密切关注并查看最终会影响主分支的更改,以便他们可以先发制人地围绕这些更改进行编码。

            【讨论】:

              【解决方案6】:

              如果您已经知道哪里有重复,那么您不需要几天的时间来重构它。

              【讨论】:

                【解决方案7】:

                有时重写是唯一的选择。好像是这样的。

                【讨论】:

                  【解决方案8】:

                  CloneDR 在大型源系统中查找重复代码,包括精确副本和接近未命中,由语言语法参数化。支持Java、C#、COBOL、C++、PHP等多种语言。

                  当它显示一组找到的克隆的参数化抽象时,它本质上是建议重构代码并实现该抽象(作为方法、函数、类,... )。

                  因此,运行 CloneDR 会获得要添加到代码中的潜在抽象列表,并且通过调用抽象来替换克隆实例会重构您的代码,从而(在某种程度上)清理它。

                  更值得注意的是,当它显示在调用抽象所需的每个克隆站点上使用的参数绑定时,它通常会显示一个错误的克隆实例,当绑定的参数在概念上不一致时很容易识别。如果参数绑定到名为 YYYY-MM-DD 的变量,其中一个是 YY-MM-DD,则“它的 4 位数年份”参数类型看起来被违反了,在这种情况下,Y2K 修复被破坏。所以检查克隆绑定经常会发现错误。

                  【讨论】:

                  • 答案在被标记为垃圾邮件后被删除。问题是要求一般实践指南。如果它要求产品推荐,我会留下来。
                  • OP 要求提供有关如何处理大量重复代码的建议,并哀叹他无法以足够快的速度提出抽象来应对。该工具专门解决了他的问题:“运行克隆检测器”以及如何应对抽象缓慢:“它向您展示了提出的抽象”。还有其他克隆检测工具。他们中的大多数都找不到未命中的克隆,也没有提供建议的抽象;所有要做的就是说:“那是一个克隆……”所以我认为这个回答是直接针对他的问题的。
                  【解决方案9】:

                  这是科学计算中非常常见的问题。减少代码大小和复杂性的一些最有效的想法需要利用假设,而科学要求您不断改变这些假设。

                  您所能做的就是尝试随时重构您的代码,并且尽量不要将自己写进任何角落。还可以与了解不弄乱的价值的优秀人士合作。

                  【讨论】:

                    猜你喜欢
                    • 2017-09-06
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-01-08
                    • 2014-12-09
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多