代码之家  ›  专栏  ›  技术社区  ›  rafek

如何重构?

  •  18
  • rafek  · 技术社区  · 16 年前

    我想知道其他开发人员是如何开始重构的。你的第一步是什么?如果重构的代码不是您的代码,那么这个过程(重构)有什么不同?重构时是否编写测试?

    14 回复  |  直到 13 年前
        1
  •  25
  •   Steven A. Lowe    16 年前
    1. 不要重构没有单元测试的非平凡的东西
    2. 编写单元测试,然后重构
    3. 重构小块并频繁地重新运行测试
    4. 当代码干燥时停止重构 * 清洁的

    * dry=不要重复

        2
  •  8
  •   Community CDub    8 年前

    你的第一步是什么?

    第一步是运行单元测试以确保它们都通过。实际上,您可能会浪费大量的时间来寻找哪些更改已经破坏了测试 之前 修改代码。

    如果重构的代码不是您的代码,那么这个过程有什么不同?

    当重构我没有编写的代码(或者我很久以前编写的代码)时,我确实在做一些小的步骤。我也可以在继续之前验证测试覆盖率,以避免依赖总是通过的单元测试…但这并不能测试我正在工作的领域。

    重构时是否编写测试?

    我通常不会,但我可以在以下情况下添加新的测试(列出不详尽的测试):

    • 一个新测试的想法在我脑海中闪现( “如果……“ -写 要知道的测试
    • 在测试覆盖范围内发现漏洞

    它还取决于正在执行的重构。在提取函数时,如果可以像以前那样以不同的方式调用它,我可以创建一个新的测试。


    以下是一些一般性建议:

    第一件事是维护 code smells 在处理代码时注意到。这就可以让人从记忆代码中所看到的东西的负担中解脱出来。也,

    当单元测试没有完全通过时,黄金法则永远不会重构。

    当代码稳定时重构,在添加您知道将受到未来重构影响的内容之前,在集成之前,尤其是在所有这些之前 在说“完成”之前 .

    在没有单元测试的情况下,您必须将要重构的代码部分置于测试之下。如果单元测试太难进行改型(通常是这样),那么您可以创建 characterization tests ,根据建议 Michael Feathers in Working Effectively with Legacy Code .简言之,它们是端到端的测试,允许您确定代码的当前行为(假定代码并非一直工作得很好)。

    不要害怕 婴儿阶梯 . 不要同时做两件事。如果您评论了一些需要重构的东西,请记下它,不要马上修复它,即使它看起来很容易。

    当测试通过时,经常签入。这样,您就可以在不丢失以前所做的操作的情况下恢复不好的重构。

    请记住,重构不会为您的客户增加价值(这可以讨论),但客户不会向您支付重构的费用。一个经验法则是在对代码进行更改或添加新功能之前重构。

        3
  •  4
  •   MarkJ    16 年前

    Martin Fowler “书” Refactoring

    顺便说一句-这是马丁·福勒自己的亚马逊执行链接,如果你想知道的话:)

        4
  •  4
  •   yegor256    14 年前

    我接受废话,让它少废话。-)

    说真的。我不会重构以创建新功能。重构发生在新事物之前。如果没有测试,我就编写测试来确保重构不会破坏任何东西。如果有测试,我就用那些。如果测试不够,我可能会写更多的测试,但是我会把这与重构分开,并首先进行。

    对我来说,第一步是注意到我可以抽象一些东西,使其更一般(并且在现在需要功能的其他地方也有用),或者我注意到一些东西是坏的,可以更好(主观的)。我不会无缘无故地重构为一般性。 YAGNI principle 应用。

    我们有共享所有权的概念,所以代码总是我的——我可能没有写过,但是在重构时我不考虑这一点。如果目的不明确,我可能会在决定需要重构之前寻求理解——尽管这几乎总是重构自身的一个原因。

        5
  •  3
  •   SmacL    16 年前

    很大程度上取决于我的目标。如前所述,您需要进行单元测试,以确保重构不会破坏任何东西,如果有,您必须投入时间来修复它。在许多情况下,我测试现有的解决方案,如果它可以工作的话,包装它而不是重构它,因为这样可以最小化中断的可能性。

    如果我必须重构,例如,我最近不得不将一组基于ASCII的C++移植到Unicode上,我倾向于确保我有好的回归测试在最终用户和单元级工作。同样,我尝试使用工具而不是手动重构,因为这不太容易出错,而且您得到的错误是系统性的,而不是随机的。

        6
  •  2
  •   J.J.    16 年前

    对我来说,首先要确保代码符合我们办公室的所有最佳实践。 例如,对Perl脚本使用严格、警告和污点。

    如果有效率或速度问题,集中精力解决。 例如,找到更好的算法,或者找到更好的方法来执行四嵌套for循环正在执行的操作。

    最后,看看是否有办法让代码更可读。这通常通过将5个执行类似操作的小脚本转换为1个模块(类)来完成。

        7
  •  2
  •   harriyott Erik Funkenbusch    16 年前

    我在编写新代码时使用单元测试进行重构。如果方法太长,或者变量名称不正确,或者我发现重复等,我还将重构旧代码,不管是我的还是其他人的。

        8
  •  2
  •   workmad3    16 年前

    从获取单元测试开始,然后使用自动重构工具。如果重构不能自动化,那么它就不是代码的真正机械转换,因此也不是重构。单元测试是为了确保您真正只是执行从一个代码库到等效代码库的机械转换。

        9
  •  2
  •   Patrick Desjardins    16 年前

    重构不需要 单元测试 是危险的。始终进行单元测试。如果您在没有良好测试的情况下更改了某些内容,那么您可能对代码的某些部分是安全的,但其他地方的某些内容可能没有相同的行为。通过单元测试,您可以保护任何更改。

    重构 其他代码 也很好,但极端情况并非如此。别人不像你那样编程是很正常的。换东西不是“好的”,因为你会用另一种方式。如果确实有必要,只需重构。

        10
  •  2
  •   Mike Burton    16 年前

    我删除了重复,它统一了代码中固有的思维模式。重构需要实现这两点。如果您有两次执行相同操作的代码,请将其重构到一个公共位置,统一抽象。如果你在三个地方有相同的字面,把它放在一个常量中,统一目的。如果您有相同的参数组,请确保它们总是以相同的顺序使用,或者更好的是,将它们放在一个共同的结构中,统一信息组。

        11
  •  2
  •   Bruce Alderman    16 年前

    比起重构自己的代码,我更不愿意重构别人编写的代码。

    如果它是由我的一个前辈写的,我通常只在函数内重构。例如,我可以用开关替换if语句。任何比这大得多的东西通常都超出范围,不在预算之内。

    对于我自己的代码,我通常在编写时重构,每当有什么东西看起来很难看或开始闻起来。现在修复它要容易得多,而不是等待它在路上造成问题。

        12
  •  1
  •   DOK    16 年前

    当你重构你写的代码时,我同意其他的海报。

    如果是你没有写的代码,尤其是有很多代码,我会从使用fxcop、Visual Studio的代码分析、devpartner等工具开始——我相信还有其他好的工具。它们会让您了解从哪里开始以及最常见的编码问题是什么。我还将进行压力测试,以了解瓶颈在哪里,因此这是您改进代码的最大回报。

    我喜欢重构我的代码,但可能做得太多了。如果你没有真正提高应用程序的性能,或者没有真正提高代码的可读性,你应该停止。重构时总是有可能引入新的bug,特别是在没有单元测试的情况下。

        13
  •  0
  •   JB King    16 年前

    第一步:识别 code smell.

    第二步:考虑替代的实现,权衡是什么,我接受哪个是“更好的”。

    第三步:实施更好的解决方案。

    如果代码是我的或不是我的,这没有什么不同,因为有时我可能会回顾几个月或几年前写的代码,它看起来像是来自其他人的代码。如果我正在开发新的方法或者代码没有足够的测试,我可以编写测试。

        14
  •  0
  •   Community CDub    8 年前

    一般方法

    我可以从鸟瞰图开始浏览软件(组件)。依赖性分析和绘图工具在这里是一个很好的帮助(参见后面的章节)。我在包级别或类级别的依赖项中寻找一个圆,或者寻找依赖项过多的类。这些是重构的好候选者。

    贸易工具

    依赖关系分析工具: