2008-10-15 48 views
18

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

+1

见http://stackoverflow.com/questions/20262/refactoring-for:

贸易

相关分析工具的工具-testability-上的现有系统。请参阅http://stackoverflow.com/questions/48817/where-to-find-resources-on-refactoring。这些都没有帮助? http://stackoverflow.com/questions/tagged/refactoring – 2008-10-20 12:00:29

回答

24
  1. 不重构任何不平凡的,不已经有单元测试
  2. 编写单元测试,然后重构
  3. 重构小块,然后重新运行测试经常
  4. 停止重构代码时干*干净

* DRY =不要重复自己

+0

DRY =不要重复自己,直到我看到它,我才知道,所以我想我会给别人一个头。 – 2008-10-17 12:07:06

+0

@ [nemo]:谢谢,为清晰起见编辑 – 2008-10-17 15:55:41

2

对我来说,首先要确保代码符合我们办公室的所有最佳实践。例如,对我们的Perl脚本使用strict,warnings和taint。

如果有efficienry或速度的烦恼集中在他们身上。 像找到一个更好的算法,或找到一个更好的方法来做什么quadruply嵌套for循环正在做的事情。

而最后看是否有一种方法可以使代码更易读。这通常通过将5个执行类似事情的小脚本转换为1个模块(类)来完成。

2

我重构,同时编写新的代码,使用单元测试。我还会重构旧代码,如果方法太长,或者变量命名不正确,或者我认为重复等,我的旧代码或我的或别人的代码都会重构。

2

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

4

我把废话,使其不那么糟糕。 :-)

重视。我不重构创建新功能。重构发生在新东西之前。如果没有测试,我会写测试以确保我不会因为重构而破坏任何东西。如果有测试,我使用这些。如果测试不够,我可能会写更多的测试,但我会认为这与重构是分开的,并且首先要做。

对我来说,第一步是注意到我可以抽象出一些东西并使其更加通用(并且在其他需要现在功能的地方很有用),或者我注意到某些东西不好,可能更好(主观)。没有理由,我不会重复概括性。适用YAGNI principle

我们拥有共同所有权的概念,使代码始终是我的 - 我可能不会写,但我不认为重构时。如果目的不明确,我可能会试图理解一些事情,然后再决定是否需要重构 - 尽管这几乎总是一个重构的原因。

2

重构没有单元测试是危险的。始终有单元测试。如果你在没有良好的测试的情况下改变某些东西,你可能对代码的某些部分是安全的,但其他地方的东西可能不会有相同的行为使用单元测试可以保护所有变更。

重构其他代码也很好,但极端不是。别人不像你这样编程是正常的。改变东西并不“友好”,因为你会以其他方式做到这一点。只需重构,如果真的有必要。

2

我删除重复,它统一了代码中固有的思维模式。重构需要实现这两件事情。如果你有两次执行同​​样的事情的代码,将它重构到一个普通的位置,统一抽象。如果你在三个地方有相同的字面量,就把它固定在一个常数上,统一目的。如果您拥有相同的参数组,请确保它们始终以相同的顺序使用,或者更好地将它们放在一个通用结构中,统一信息组。

1

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

如果它是你没有写的代码,尤其是如果有很多代码的话,我会先用fxCop,Visual Studio的代码分析,DevPartner等工具开始 - 我确信还有其他很好的代码。他们会告诉你从哪里开始以及最常见的编码问题。我也会做压力测试,看看瓶颈在哪里,因此你在改进代码方面的努力可以获得最大的回报。

我喜欢重构我的代码,但它可能过分。如果你没有真正提高应用程序的性能,或者严重提高代码的可读性,你应该停下来。重构时总会有引入新bug的可能性,尤其是如果你没有进行单元测试的话。

3

取决于我的目标。如前所述,您需要进行单元测试以确保您的重构没有破坏任何东西,并且如果需要,您必须花时间修复它。对于很多情况,我测试现有的解决方案,如果它工作,将其包装而不是重构它,因为这可以最大限度地减少中断的可能性。

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

2

我更不愿意重构他人编写的代码,而不是重构我自己的代码。

如果它是由我的一位前任编写的,我通常只会在函数中重构。例如。我可能会用开关替换if语句。任何比这更大的东西通常超出范围,并且不在预算范围内。

对于我自己的代码,当我写东西时,通常会重构,只要有东西看起来很丑或开始闻起来。现在修复它很容易,而不是等待它导致问题。

8

你的第一步是什么?

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

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

我当然在重构代码的时候做的步骤比较小,我没写(或者我很久以前写的代码)。我也可以在进行之前验证测试覆盖率,以避免依赖总是通过的单元测试......但是这不会测试我正在工作的区域。

你在重构时编写测试吗?

我通常不这样做,但我可能会增加在下列情况下新的测试(名单并不详尽):在我的脑海一个新的测试闪光的

  • 想法(“发生什么如果。 ?..” - 写 测试就知道了)
  • 在测试覆盖率

也要看正在执行的重构发现孔。当提取函数时,如果可以像以前那样调用不同的方法,我可以创建一个新的测试。


这里有一些一般性的建议:

第一件事情就是保持对代码的工作,同时注意到code smells的列表。这可以让你的头脑免于回忆代码中看到的内容。

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

重构当代码是稳定的,你知道会被未来的重构受到影响,之前整合所有以上之前说你做增加一些之前。

在没有单元测试的情况下,您必须将您想要重构的部分代码放在测试中。如果单元测试太难改造,通常情况下,您可以按Michael Feathers in Working Effectively with Legacy Code的建议创建characterization tests。简而言之,它们是端到端的测试,可以让您确定代码的当前行为(不会始终保持完美)。

不要害怕做宝贝步骤。不要同时做两件事。如果您想要重构某些内容,请记下它,即使看起来很简单,也不要立即修复它。

经常检查,当测试通过。这样你就可以恢复一个糟糕的重构,而不会丢失之前完成的工作。

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

0

第一步:确定一个code smell.

第二步:考虑替代实现,什么权衡是和我在条款接受这些是“更好”。

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

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

0

一般方法

我可以通过从鸟瞰图软件(组件)偷看开始了。依赖分析和图形工具在这里很有帮助(参见后面的章节)。我在包级别或类级别的依赖关系中查找一个圆圈,也可以查找具有太多依赖关系的类别。这些是重构的好选择。