什么时候重构代码?

时间:2010-10-22 21:57:00

标签: language-agnostic refactoring

现场:
你永远不会有时间去做 2.“语境转换”在精神上很昂贵(很难留下你正在做的事情) 这通常不是一件容易的事 人们总是害怕你会破坏现在正在发挥作用的东西。

另一方面:
1.使用该代码容易出错 2.随着时间的推移,您可能会意识到,如果您在第一次看到代码时重构了代码,那么从长远来看,这将节省您的时间。

所以我的问题是 - 实际上 - 你什么时候决定重构你的代码?

感谢。

9 个答案:

答案 0 :(得分:8)

有几点意见:

  

现场:   你没有时间去做。

如果你将重新分解视为与编码分开的东西(而不是正确编码的内在部分),如果你无法管理时间,那么,你永远不会有时间。

  
      
  1. “上下文切换”在精神上很昂贵(很难留下你正在做的事情)。
  2.   

见上述观点。重构是良好编码实践的积极组成部分。如果将两者分开,就好像它们是两个不同的任务一样,那么1)您的编码实践需要改进/成熟; 2)如果您的代码严重需要重构,您将参与严格的上下文切换(同样,代码质量。 )

  
      
  1. 这通常不是一件容易的事。
  2.   

仅当您生成的代码不适合重构时。也就是说,难以重构的代码展示了以下一个或多个(列表不是普遍包含的):

  1. High cyclomatic complexity
  2. 每个班级(或程序)不承担任何责任,
  3. 高耦合和/或差的低内聚力(又名差LCOM metrics),
  4. 结构不佳
  5. 不遵循SOLID principles
  6. 在适当的时候不遵守Law of Demeter
  7. 在不合适时过度遵守Law of Demeter
  8. 针对实现而不是接口进行编程。
  9.   
        
    1. 总是害怕你会破坏现在正在发挥作用的东西。
    2.   

    测试?验证?分析?在检查源代码控制之前(当然在交付给用户之前)中的任何一个?

      

    另一方面:   1.使用该代码容易出错。

    只有从未经过测试/验证和/或没有清楚地了解可能容易出错的代码可以接受的条件和使用模式。

      
        
    1. 随着时间的推移,你可能会意识到如果你想重构代码了   第一次看到它 - 从长远来看,这可以节省你的时间。
    2.   

    这种认识不应该随着时间的推移而发生。良好的工程和工作道德要求在人工制品(硬件或软件)正在制定时实现这种实现。

      

    所以我的问题是 - 实际上 - 你什么时候决定重构你的代码?

    实际,当我编码时;我检测到需要改进的区域(或者在需求或期望发生变化后需要修正的区域);我有机会在不牺牲截止日期的情况下改进它。如果我不能在那一刻重新考虑因素,我只需记录感知缺陷并创建一个可行的,切合实际的计划来重新审视用于重构的工件。

    在现实生活中,有些时候我们会编写一些丑陋的kludge只是为了让事情得以运行,或者因为我们已经筋疲力尽或其他什么。这是现实。我们的工作是确保这些事件不会堆积并且无人看管。而关键是在编码时重构,保持代码简单,并具有良好,简单和优雅的结构。而“优雅”我并不是指“聪明屁股”或深奥,而是显示通常被认为是可读的,简单的,可组合的属性(以及实际应用时的数学属性)。

    良好的代码适合重构;它显示了良好的指标;它的结构类似于computer science function compositionmathematical function composition;它有明确的责任;它使其不变量,前后条件明显;等等。

    希望它有所帮助。

答案 1 :(得分:7)

  1. Whenever it smells,我重构了。我现在可能不会完美,但我至少可以向更好的状态迈出一小步。随着时间的推移,这些微小的变化确实会增加......
  2. 当我注意到气味时,如果我处于中间位置,并且修复它并不是微不足道的(或者我只是在释放之前),我可能会做一个(精神或纸质)注释,一旦我发现它完成了主要任务。
  3. 练习让一个更好:-)但如果我没有看到问题的解决方案,我把它放在一边,让它冲泡一段时间,与同事讨论,或者甚至将它贴在SO上; - )< / LI>
  4. 如果我没有单元测试并且修复不是微不足道的,我会从测试开始。如果测试也不是微不足道的,我会应用第2点。

答案 2 :(得分:7)

我看到的最常见的错误之一是人们将“重构”一词与“大变革”联系在一起。

重构代码并不总是很大。即使是很小的更改,例如将bool更改为正确的枚举,或者将方法重命名为更接近实际函数与意图,也是重构代码。除了里程碑的结束之外,我每次登记都会尝试至少进行一次非常小的重构。而且你会惊讶于它在代码中产生明显差异的速度有多快。

更大的变化确实需要更大的规划。在正常的开发周期中,我尝试每两周安排一次约1/2,以解决更大的重构变化。这是足够的时间来对代码库进行实质性的改进。如果重构每天失败1/2,则不会造成太大的损失。并且它很少完全丢失,因为即使是失败的重构也会教你一些关于代码的东西。

答案 3 :(得分:2)

一旦发现我在重复我的自我,我就开始重构。 DRY原则ftw。

此外,如果方法/函数变得太长,以至于它们看起来难以处理,或者它们的目的被函数的长度所掩盖,我将其分解为私有子函数来解释实际情况。

最后,如果一切都正常运行,并且代码速度慢,那么为了提高性能,我会开始考虑重构。

答案 4 :(得分:2)

需要重构时重构代码。我寻找的一些症状:

  • 在类似对象中重复代码。
  • 在一个对象的方法中重复代码。
  • 任何时候需求已经改变两次或更多。
  • 任何时候有人说“我们将在以后清理它”。
  • 任何时候我通过代码阅读并摇头思考“goofball做了什么”(即使有问题的goofball是我)

一般而言,较少的设计和/或不太明确的要求意味着更多的重构机会。

答案 5 :(得分:2)

在实现新功能时,我经常注意到,如果我正在处理的代码以不同的方式构建,那么任务会更简单。在这种情况下,我通常会退后一步,尝试先进行重构,只有在完成后才能继续实现新功能。

我也有习惯跟踪笔记或错误跟踪器中出现的所有潜在改进。这些想法在那里烘烤了一段时间,其中一些不再那么引人注目了,合理的想法在一天中实施,我专注于小任务。

答案 6 :(得分:0)

这可能听起来像个笑话,但实际上,我只是在事情变得“混乱”时重构。当一个简单的任务开始花费更多的时间和平常,当我不得不扭曲我的想法,记住什么功能正在做什么等等。此外,如果代码开始运行缓慢并且不是因为我在开发环境(很多变量输出等)中运行,如果我无法优化它,我重构代码。正如你所说,从长远来看,它是如此。

尽管如此,我始终确保在开始之前有足够的时间来思考问题,所以我不会介入这个问题。

干杯!

答案 7 :(得分:0)

当下列其中一项成立时,我通常会重构:

  • 我没有更好的事情要等待下一个项目进入我的收件箱
  • 我对代码所做的添加/更改无法正常工作,除非,或者更好,如果我重构
  • 我对编写代码的方式感到不满意

答案 8 :(得分:0)

Martin Fowler在他的book中,如果同一个名字暗示你是第三次在一段代码中进行另一次更改的话。第一次在街区,你碰巧注意到你应该重构,但没有时间。第二次回来......同样的事情。第三次回到现在的重构。 另外,我读了当前发布的smalltalk(我认为是squeak.org)的开发人员说他们经历了几周的激烈编码......然后他们退后一步看看可以重构的内容。 就个人而言,我必须抵制重构的冲动,因为我编码或“瘫痪”。