你应该多久重构一次?

时间:2008-09-26 16:59:25

标签: refactoring

几个星期前我与一些同事进行了重构讨论,我似乎是少数人认为“早期重构,经常重构”是一种很好的方法,可以防止代码变得混乱和不可维护。许多其他人认为它只属于项目的维护阶段。

如果您有意见,请为其辩护。

25 个答案:

答案 0 :(得分:76)

就像你说的那样:早期重构,经常重构。

早期重构意味着必要的变化仍然是我的想法。重构通常意味着变化往往更小。

延迟重构只会导致一团糟,这使得重构更加困难。我发现混乱后立即清理,防止它堆积起来,以后再成为问题。

答案 1 :(得分:34)

我会在功能完成后重构代码(所有测试都通过)。这样我就可以清理它,但在我的脑海中仍然是新鲜的,并且在其他人看到第一个版本有多丑之前。

初次登记后,我每次触摸一段代码时都会重构。重构不是你应该留出的时间。这应该是你刚才做的事情。

答案 2 :(得分:22)

你用两个帽子编写代码。 刚刚得到的工作帽子和我需要明白这个明天的帽子。显然,第二个帽子是重构帽子。因此,每当你做了一些工作但你(不可避免地)引入了像重复代码,长方法,脆弱的错误处理,错误的变量名等等气味时你重构...

在尝试让某些东西工作时(即戴上两顶帽子)进行重构对于非平凡的任务来说是不切实际的。但推迟重构直到第二天/周/迭代是非常糟糕的,因为问题的背景将从你的脑袋消失。因此,尽可能经常在帽子之间切换,但绝不要将它们组合起来。

答案 3 :(得分:18)

我重构了每一次机会,因为它让我能够将我的代码磨练成最好的代码。即使在积极开发以防止首先创建不可维护的代码时,我也会这样做。它经常让我在做出不可修复之前理顺一个糟糕的设计决定。

答案 4 :(得分:13)

重构的三个充分理由:

  • 您的原始设计(可能在非常小的区域,但设计仍然是)是错误的。这包括您发现常见操作并希望共享代码的位置。
  • 你正在迭代设计。
  • 代码很糟糕,需要大修。

不重构的三个好理由:

  • “这看起来有点乱”。
  • “我不完全同意最后一个人这样做的方式。”
  • “它可能更有效率”。 (问题在于'可能')。

“凌乱”是有争议的 - 有一个有效的论据被称为“修复破窗”或“代码卫生”,这表明如果你让小东西滑动,那么你将开始让大事物滑动。这很好,并且记住是一件好事,但请记住这是一个类比。为了寻找最清晰的解决方案,它不能以无休止的方式解决这些问题。

您重构的频率应取决于良好原因发生的频率,以及您的测试过程如何保护您免于引入错误。

重构本身并不是目标。但是如果某些东西不起作用,就必须修复它,这在初始开发中和在维护中都是如此。对于非平凡的改变,重构几乎总是更好,并且干净地整合新概念,而不是用大块垃圾修补一个地方,以避免在其他地方发生任何变化。

对于它的价值,我认为没有改变界面,只要我掌握了使用它的内容,并且所得到的更改的范围是可管理的。

答案 5 :(得分:7)

正如书中所说,你在

时重构
  • 您添加了一些代码...新功能
  • 修复错误/缺陷时
  • 当您与多人进行代码审核时
  • 当你发现自己第三次复制某些内容时...... 3次攻击规则

答案 6 :(得分:6)

很多时候,当我清除想法时,我的代码开始非常紧密耦合和混乱。当我开始更多地理解这个想法时,逻辑分离开始越来越清晰,我开始重构。这是一个不变的过程,因为每个人都建议应该“早期和经常”完成。

答案 7 :(得分:6)

我试图遵循这个座右铭:让你触摸的所有代码都比以前更好。

当我进行修复或添加功能时,我通常会利用这个机会对受影响的代码进行有限的重构。通常这会使我更容易进行预期的更改,因此它实际上不需要任何费用。

否则,你应该预算专门的重构时间,如果你不能,因为你总是在灭火(我想知道为什么)那么你应该强迫自己重构,当你发现变化变得比应该变得更难以及何时“代码闻起来“只是难以忍受。

答案 8 :(得分:4)

每当我阅读任何内容时,我都会重构,并且可以使更具可读性。不是重大的重组。但是,如果我对自己说“这个List包含什么?哦,Integer s!”然后我会将其更改为List<Integer>。此外,我经常在IDE中提取方法,以便为几行代码添加一个好名称。

答案 9 :(得分:4)

我在以下时间重构:

我正在修改代码,我对此感到困惑。如果我需要一段时间来筛选它,它需要重构。

我正在创建新代码,并且在它“工作”之后。很多时候我会把事情搞定,因为我正在编码,我意识到“嘿,我需要重做我做了20行,只做了一些改动”。那时我重构并继续。

在我看来,唯一能阻止你做这件事的是时间限制。无论喜欢与否,有时你只是没有时间去做。

答案 10 :(得分:4)

机会主义地重构!只要它 easy 就可以。

如果重构很困难,那么你是在错误的时间(当代码不需要它时)或代码的错误部分(在那里获得更好的效率)。 (或者你还没有那么擅长重构。)

为“维护”保存重构是一个重言式。重构维护。

答案 11 :(得分:4)

就像国家公园 - 总是让它​​比你发现它好一点。

对我而言,这意味着每当我打开代码,并且不得不抓挠头脑去弄清楚发生了什么,我应该重构一些东西。我的主要目标是可读性和理解力。通常它只是为了清晰起见而重命名变量。有时它正在提取方法 -

例如(琐碎的),如果我遇到了

temp = array[i];
array[i] = array[j];
array[j] = temp;

我可能会用swap(i,j)方法替换它。

编译器可能无论如何都会内联它,而swap()会在语义上告诉每个人发生了什么。

话虽这么说,我自己的代码(从头开始),我倾向于重构设计。 我经常发现在具体课堂上工作更容易。完成并调试后,我将拉出旧的Extract Interface技巧。

我会把它留给同事重构以便于阅读,因为我太靠近代码注意漏洞。毕竟,我知道我的意思。

答案 12 :(得分:3)

答案总是如此,但更具体地说:

  • 假设您为每个任务分支,然后在每个新分支上进行QA。
  • 如果你在主干中开发所有内容,那么在每次提交之前。
  • 维护旧代码时,请将上述内容用于新任务,旧代码会对主要版本进行重构,以获得额外的QA。

答案 13 :(得分:2)

如果您有一个可以安全地进行更改的重构工具,那么只要代码编译,您就应该重构,如果它会使代码更清晰。

如果你没有这样的工具,你应该在测试为绿色时重构,如果它会使代码更清晰。

进行小的更改 - 重命名方法以使其更清晰。提取一个类,使一组相关变量明确相关。重构不是要做出大的改变,而是要让事情一分一秒地变得清洁。重构是在每餐后清理你的餐具,而不是等到每个表面被脏盘子覆盖。

答案 14 :(得分:2)

不断地,在合理范围内。您应该始终在寻找改进软件的方法,但是必须小心避免为了重构而重构的情况(Refactorbation)。

如果你能说一个重构可以使代码更快,更容易阅读,更容易维护或更容易,或者为我所说的业务提供一些其他价值!

答案 15 :(得分:2)

“早期重构,经常重构”是一个富有成效的指导方针。虽然这种假设你真的知道代码。系统越老,重构就越危险,并且需要更多的审议。在某些情况下,重构需要是管理任务,具有工作级别和时间估计等。

答案 16 :(得分:2)

我将重构本地化为与当前任务相关的代码。我尝试在前面进行重构。我单独提交这些更改,因为从功能的角度来看,它与实际任务无关。这样代码就更清晰了,修订历史也更清晰。

答案 17 :(得分:2)

每次遇到需要时。至少当你要改变一段需要重构的代码时。

答案 18 :(得分:1)

重构通常可以节省一天,或者至少节省一些时间。我正在进行一个项目,在我们达到一些里程碑后,我们重构了所有代码。这是一个很好的方式,因为如果我们需要破解不再有用的代码,那么就可以更容易地修补我们需要的任何新东西。

答案 19 :(得分:1)

我们正在就此问题进行讨论。我们或多或少同意“写它以便它起作用,然后修复它”。但我们在时间方面有所不同。我更“立即修复”,我的同事更“在下一次迭代中修复它”。

一些支持他的报价:

Douglas Crockford,高级Javascript架构师雅虎:

  

每7次冲刺重构一次。

Ken Thompson(unix man):

  

代码本身几乎腐烂而且它是   要改写。即使什么都没有   由于某种原因,它已经改变了。

我希望一旦完成任务,提交的代码就是你可以在2个月内回来并想“是的,我在这里做得很好”。我不相信以后很容易找到时间来修复它。从我的观点来看,相信这有点天真。

编辑:拼写错误

答案 20 :(得分:1)

绝对一旦看似权宜之计。如果你不这样做,疼痛就会增加。

自从切换到Squeak(我现在似乎提到每个帖子)后,我意识到原型设计过程中的许多设计问题都会消失,因为在这种环境下重构非常容易。说实话,如果你没有一个基本上没有重构的环境,我建议你试着发出吱吱声就知道它会是什么样了。

答案 21 :(得分:0)

我认为这篇Top 100 Wordpress博文可能会有一些很好的建议。 http://blog.accurev.com/2008/09/17/dr-strangecode-or-how-i-learned-to-stop-worrying-and-love-old-code/

答案 22 :(得分:0)

如果没有破坏,请不要重构它。

我说重构的时间属于初始编码阶段,你可以随心所欲地多次进行重构。一旦它掌握在客户手中,那么它就变成了另一回事。你不想为自己整理代码工作,只是发现它被运送并破坏了某些东西。

首次交付重构后的时间是你说你会这样做的时间。当代码有点太臭时,就有一个包含重构的专用版本,可能还有一些更重要的修复。这样,如果你碰巧打破了某些东西,你知道它出错的地方,你可以更容易地解决它。如果你一直在重构,你会破坏它,你不会知道它被破坏,直到它得到QAd,然后你将很难找出错误修复/功能代码更改是否导致问题,或一些重构你很久以前的表现。

当代码看起来与以往大致相同时,检查cbreaking更改会轻松得多。重构很多代码结构,你可以使它几乎不可能,所以只有当你认真的意思时才重构。像对待任何其他产品代码一样对待它,你应该没问题。

答案 23 :(得分:0)

关于这个主题有很多观点,有些观点与特定的发展方法或方法有关。使用TDD时,尽早进行重构,正如您所说,通常是一种受欢迎的方法。

在其他情况下,您可以根据需要进行重构。例如,当您发现重复的代码时。

当遵循更详细的前期设计的传统方法时,重构可能不那么频繁。但是,我建议不要在项目结束前留下重构。您不仅可能会出现问题,可能会在UAT之后出现问题,通常也会出现重构变得越来越困难的情况。出于这个原因,经典项目的时间限制导致重构和额外的测试被删除,当维护开始时你可能已经创建了一个意大利面条代码怪物。

答案 24 :(得分:0)

我认为当你正在处理其中的一部分时,你应该重构一些东西。意味着如果你必须增强函数A,那么你应该在之前(以及之后?)重构它。如果你没有对这个功能做任何事情,那么只要你还有别的事可做,就保持原样。

不要重构系统的工作部分,除非您必须更改它。