2010-10-22 61 views
4

手头上有:
1.你永远没有时间做到这一点。
2.“上下文切换”在精神上非常昂贵(难以让你在中间做什么)。
3.通常不是一件容易的事。
4.总会有人担心你会破坏正在工作的东西。什么时候重构代码?

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

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

谢谢。

+1

可能重复的[你什么时候重构代码?](http://stackoverflow.com/questions/971863/when-do-you-refactor-code) – 2010-10-22 22:00:18

+1

当俚语对科技字的比例超过N,Where N是一个取决于当地文化和项目难度的实验确定的值。 – 2010-11-10 01:37:15

回答

7

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

重构代码并不总是很大。即使是很小的变化,例如将bool更改为适当的枚举,或者将方法重命名为更接近实际功能与意图也是重构代码。除了一个里程碑的结束之外,我每次登记时都会尝试至少进行一次非常小的重构。您会惊讶于这会在代码中产生明显的差异。

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

7
  1. Whenever it smells,我重构。我现在可能做不到完美,但我至少可以向更好的状态迈出一小步。随着时间的推移,这些小小的变化会加起来......
  2. 如果我在注意到气味,修复它并不是微不足道(或者我只是在释放之前)时,我可能会做出一个(心理或纸张)笔记在我完成主要任务后返回。
  3. 练习使一个更好:-)但是,如果我没有看到问题的解决方案,我把它放在一边,让它酿造一段时间,与同事讨论,甚至张贴在SO ;-)
  4. 如果我没有单元测试,并且修复不是微不足道的,我从测试开始。如果测试不平凡要么,我申请2点
+0

+1:引用奶奶贝克 - “如果它闻起来,改变它。” – 2010-10-22 22:14:23

+0

@donroby,马丁福勒实际上不是吗?当然,两者都可以发明这种说法,但至少我认为我已经在重构中首先阅读了它。 – 2010-10-22 22:18:33

+0

+1进行气味测试。 – 2010-10-22 22:25:29

0

这听起来像一个笑话,但说真的,当事情“变得一团糟”我只重构。当一个简单的任务开始需要更多的时间和通常的时候,当我不得不扭动我的脑海以记住什么功能在做什么等等。另外,如果代码开始运行缓慢,并且不是因为我运行在开发环境(很多变量输出等),如果我无法优化它,我重构代码。正如你所说,从长远来看它是受到嘲弄的。

不过,我总是确保在开始之前我有足够的时间来思考问题,所以我没有进入这个位置。

干杯!

+0

我不同意。这种态度是什么导致你没有时间重构的情况。把它关掉,直到它真的很痛 - 然后,它伤害太多。相反,通过一些小步骤不断重构,始终保持代码比开始时更好 - 然后代替“变得杂乱”,代码将“变得干净”。 – 2010-10-23 14:42:04

+0

@Carl Manaster这真的取决于你“弄乱”的理解。我所说的或多或少都在第一个答案的范围内,只是从来不知道这里有一个名字。除非我没有时间重构,否则我从不放弃它。关于小步骤,我认为它们是必要的,但是像我改变变量类型或方法的小东西在我看来并不是真正的重构。重新思考更大规模的课程和方法时,重构就会到位,但那可能只是我。 – Claudiu 2010-10-23 14:46:57

+0

我建议你阅读Martin Fowler的书,他在那里为术语“重构”提出了一个细致而清晰的定义。这也是您可以在哪里找到“改变它闻起来”的报价。我使用他的定义,并且非常清楚地包括重构与重命名方法一样微不足道。你说这些东西不是在“你的意见”中重构,这很好,但是从一个像他这样的重要术语的精心布置的标准参考定义开始工作,可以帮助我们进行更有成效的讨论。 – 2010-10-23 15:08:34

2

我开始重构一旦我发现我重复我的自我。干燥原则ftw。另外,如果方法/函数的时间太长,或者它们看起来很笨重,或者它们的目的被函数的长度所掩盖,我会将它分解成私有的子函数,以解释实际发生的事情。最后,如果一切正常并且正在运行,并且代码速度很慢,为了提高性能,我开始考虑重构。

+1

+1,但我建议分离重构和优化的概念。 – TrueWill 2010-10-22 22:20:27

+0

可能,但是我真的在一些真棒和优雅的重构上取得进展的情况往往是由于性能增强的刺激。特别是在遗留代码的情况下。 – Gopherkhan 2010-10-22 23:51:23

0

我平时重构当以下条件之一为真:

  • 我没有什么好做,等待下一个项目来我的收件箱
  • 的添加/更改我正在给该代码不能工作,除非,或者会更好,如果我重构
  • 我对代码布局
2

重构代码当需要重构的方式审美不满。我寻找的一些症状:

  • 重复类似对象中的代码。
  • 在一个对象的方法内重复代码。
  • 任何时候需求已经改变了两次或更多。
  • 任何时候有人说“我们会在晚些时候清理它”。
  • 任何时候,我通过代码阅读和动摇我的脑袋思考“什么goofball这样做”(即使有问题的goofball是我)

在一般情况下,无设计和/或不太清楚的要求,意味着更oppurtunities进行重构。

2

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

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

8

一对夫妇的意见:

在手: 1.你从来没有时间去做。

如果你把重新分解的东西从编码(而不是体面编码的固有部分)分开,如果你不能管理时间,那么是的,你永远不会有时间上的方便。

  1. “上下文切换”是精神上贵(难以离开你在它的中间做什么)。

请参阅上面的上一点。重构是良好编码实践的一个活跃组成部分。如果将两者分开,就好像它们是两项不同的任务一样,那么1)您的编码实践需要改进/成熟; 2)如果您的代码严重需要重构(即代码质量),则将进行严重的上下文切换。 )

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

仅当您生成的代码不适合重构。也就是说,代码难以重构表现出下列的一种或多种(列表不是普遍含):

  1. High cyclomatic complexity
  2. 每类(或过程)没有单一的责任,
  3. 高耦合和/或差的内聚力差(又名差LCOM metrics),
  4. 差结构
  5. 不遵循SOLID principles
  6. 适当时,不遵守Law of Demeter
  7. 不适当时,过度遵守Law of Demeter
  8. 针对实现而不是接口进行编程。
  1. 总是有恐惧,你会打破东西是现在的工作。

测试?验证?分析?在进入源代码控制之前(以及在交付给用户之前),这些都是?

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

如果从未测试/验证和/或如果存在的在其下可能容易出错代码可接受操作条件和使用方式没有明确的认识。

  1. 随着时间的推移,你可能会意识到,如果你会重构代码的 你第一次看到它 - 这将对您节省时间的长远之计。

该实现不应该随着时间发生。良好的工程和职业道德要求在工件(硬件或软件)正在制造时实现这种实现。

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

实际上,当我编码;我发现一个需要改进的领域(或者需求或期望发生变化后需要改进的领域);我有机会在不牺牲期限的情况下改进它。如果在那一刻我不能重新考虑因素,我只需记录下所发现的缺陷,并创建一个可行的,现实的计划来重新构建重构的工件。

在现实生活中,会有一些时刻我们会编写一些丑陋的kludge来让事情继续下去,或者因为我们耗尽,疲惫或者其他任何事情。这是现实。我们的工作是确保这些事件不会堆积并无人看管。关键在于在编码时重构代码,保持代码简单并且具有优良,简单和优雅的结构。 “优雅”我并不是指“聪明屁股”或深奥的,而是显示通常被认为是可读,简单,可组合的属性(以及实际应用时的数学属性)。

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

希望它有帮助。

+1

+1为综合答复,但现在的代码,没有考虑到你提到的大多数标准,我真的没有时间( - :(我不是那个人写的) 。我的意思是提出这样的问题 - 什么时候它变得如此难以忍受,以至于你决定必须重构它,尽管时间(和其他)受到限制 – 2010-10-22 22:37:53

+0

@Oren - Ouch,你似乎处在一个狭窄的角落里,当它变得难以忍受时你会花费大量的时间去尝试正确地实现一个变更,并且你也花费大量的时间来确定这个变更是否会破坏别的东西如果退化发生的可恢复性以外的话,重构不是一个可行的选择可悲的是,当不加限制时,热力学第二定律(熵)也适用于软件,当发生这种情况时,我们必须承担它,重写它或者离开另一份工作(因为做这种“长期” 。) – 2010-10-22 22:50:07

+1

@Oren - 理想情况下,变化的成本应该是可以预测的,并且与变化的大小成正比。平均而言,一个统一的需求变更应该触发一个可预测大小的代码变更(从而导致成本)。每隔一段时间需要一次。更改可能会触发非常大的代码更改(或更改大小不容易预测)。这很好。当你永远无法可靠地预测变更的成本(根据可预测的和成比例的代码变更),那么事情变得“难以忍受”......因为你不会完全知道你在每次变更请求时会得到什么:/ – 2010-10-22 22:55:46

0

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

相关问题