什么是重构,什么是只修改代码?

我知道重构是“改变程序的结构,使function不被改变”。 我正在和我正在和大学的最后一年的项目合作的一些人谈话,我很惊讶他们有一个更为广泛的 (为了更好的字眼)重构的观点。

我认为重构就像提取方法和重命名类一样。 他们还提出了诸如改变数据结构(比如Java LinkedListArrayList ),改变algorithm(使用合并sorting而不是冒泡sorting),甚至将大块代码重写为重构等。

我很确定他们是错的,但是我不能给出一个很好的理由,因为他们所提出的build议确实改变了这个计划(并且可能会更好)而不改变它的行为。 我是对的,更重要的是,为什么?

Martin Fowler的“重构:改进现有代码的devise”可能是参考:

重构是用于改进现有代码库devise的受控技术。 它的实质是应用一系列小的行为保存转换,每个转换“太小,不值得去做”。 然而,这些转变的累积效应是相当显着的。 通过小步骤完成它们,可以降低引入错误的风险。 您还可以避免在进行重组时使系统崩溃 – 这使您可以在较长的时间内逐渐重构系统。

重构与unit testing并驾齐驱。 在重构之前编写testing,然后在重构中有一个置信水平(与testing覆盖率成正比)。

一个很好的参考是: 关于重构的信息

福勒(Fowler)在修改代码和修改代码之间绘制了一条简洁的界限,这些修改会影响其行为。 他称那些不是“重构”的。 这一个重要的区别,因为如果我们将工作分成重构和非重构的代码修改活动(福勒称之为“戴不同的帽子”),我们可以应用不同的适合目标的技术。

如果我们正在进行重构或保留行为的代码修改:

  • 我们所有的unit testing都应该在修改之前和之后通过
  • 我们不需要修改任何testing,也不需要编写任何新的testing
  • 当我们完成时,我们期待更清晰的代码
  • 我们不期望新的行为

如果我们正在做一个改变行为的代码:

  • 我们期待新的行为
  • 我们应该写新的testing
  • 当我们完成的时候我们可能会弄脏代码(然后应该重构它)

如果我们忽视这个区别,那么我们对任何给定的代码修改任务的期望是混乱和复杂的,或者比我们注意到的更复杂或者更加混乱和更复杂。 这就是为什么这个词及其意义是重要的。

给我的看法:

小的增量更改,使代码处于比find的更好的状态

肯定是: “化妆品”的变化,不直接关系到function(即不作为变更请求计费)。

绝对不会:重写大块显然违反了“小增量”部分。 重构通常被用来作为重写的对立面 :而不是重新做,改善现有的。

绝对可能:更换数据结构和algorithm有些是边界情况。 国际海事组织决定的区别在于小步骤:准备好交付,准备好处理另一个案件。


例如:假设你有一个报告随机数发生器模块,由于使用了一个向量而变慢了。 你已经描述过这个向量插入是瓶颈,但不幸的是,这个模块在许多地方都依赖于连续的内存,所以当使用列表的时候,事情就会自然地中断。

重写意味着将模块从一个更好,更快的build筑物扔掉,只是从旧build筑物中挑选一些。 或者编写一个新的核心,然后将其安装到现有的对话框中。

重构将意味着采取小的步骤来删除指针算术,以便开关。 也许你甚至可以创build一个包装指针算术的实用函数,用对该函数的调用replace直接的指针操作,然后切换到一个迭代器,这样编译器就会抱怨仍然使用指针算术的地方, 然后切换到list ,然后删除ultilityfunction。


背后的想法是,代码变得更糟。 修复bug和添加特性时,质量衰减很小 – variables的含义微妙地变化,函数获得一个额外的参数,打破隔离,循环变得复杂等等。这些都不是一个真正的bug,你可以不要说线数会使循环变得复杂,但是会伤害可读性和维护。

同样,改变一个variables名或提取一个函数,并不是他们自己的明显改进。 但是总的来说,他们抵抗缓慢的侵蚀。

就像每天落在地上的鹅卵石墙。 而且每天都有一位路人把它拿起来放回去。

考虑到Martin Fowler的定义,

重构是重构现有代码体系的一种有纪律的技术,在不改变其外部行为的情况下改变其内部结构。

我认为你显然是对的

他们还提出了诸如改变数据结构(比如Java LinkedList到ArrayList),改变algorithm(使用合并sorting而不是冒泡sorting),甚至将大块代码重写为重构等。

改变一个algorithm到更快的速度显然不是重构,因为外部行为被改变了! (再说一遍,如果效果从来不明显,那么也许你可以称之为重构 – 也是不成熟的优化。:-)

这是我的宠物; 当人们使用术语sloppily时,这很烦人 – 我甚至偶尔会遇到一些可能随便使用重构来进行基本上任何更改或修复的人。 是的,这是一个时髦和冷静的stream行语,所有的,但改变改写性能改善这样的简单的旧术语没有什么不对。 我们应该在适当的时候使用这些方法,并且在真正改善软件的内部结构时保留重构 。 在一个开发团队中,尤其是有一个用于准确讨论你的工作的共同语言是很重要的。

我认为你是对的,但是对一个词的含义的争论并不是特别有趣或者富有成效。

如果一段代码的接口发生了变化,那么我认为这不仅仅是重构。

典型的重构案例是

  • “哦,我所有的unit testing都运行了,但是我认为我的代码可以变得更干净”
  • 将代码更改为更易读/更清晰/高效
  • 重新运行unit testing(不改变testing),并检查他们仍然工作

这意味着术语重构与您正在讨论的接口有关。 也就是说,你可以重构一个接口背后的代码,而更广泛地改变另一个接口的代码(也许这就是你和你的同事之间的混淆?)

http://en.wikipedia.org/wiki/Code_refactoring

代码重构是改变计算机程序的内部结构而不修改其外部function行为或现有function的过程,以便改进软件的内部非function特性,例如改善代码可读性,简化代码结构,改变代码遵循给定的编程范例,提高可维护性,提高性能或提高可扩展性。

我同意重构代码包括破坏现有的代码。 只要确保你有unit testing,这样你就不会引入任何错误,并且其余的代码会被编译。 使用像Resharper for C#这样的重构工具使得这非常简单!

  • 使代码更易于理解
  • 清理代码并使之更加整洁
  • 删除代码! 冗余的,未使用的代码和注释应该被删除
  • 提高性能
  • 制作更通用的东西。 从最简单的事情开始,然后重构它,使其更易于testing/隔离或通用,以便通过多态性以不同的方式工作
  • 保持代码干爽 – 不要重复自己,所以重构会话可能需要重复一些代码并将其重构为单个组件/类/模块。

我不同意 :

在软件工程中,“重构”源代码意味着在不改变其整体结果的情况下对其进行改进[…]

你已经知道用于重构子集的更精确的术语,是的,这是一个非常通用的术语。

我认为没有人能从“重构”这个术语中得到太强的定义。 你如何看待它和你的同事之间的边界是模糊的,可以靠近他们或你的看法取决于许多事实。 既然它是dynamic的,我们试着去定义它。 首先定义您正在尝试重构的系统或子系统的边界。

如果它是一个方法保存名称,input参数,返回值的types和可能抛出的语句固定。 应用方法中的所有更改,而不改变在外部查看的方式。

如果您重构一个类修复其公共API并使用重命名variables,则提取方法和所有其他可用技术将该类更改为更具可读性和/或更高性能。

如果你正在重构的代码的一部分是一个包或一个模块,那么它里面的重构可能会重命名类,删除,介绍接口,推/拉代码到超级/子类中。

如果你想读一些为什么重构很重要的技巧,为什么你总是不满意你的旧作,我可以推荐新的博客文章。 这将回答一些关于重构的问题,如何说服你的老板,这是重要的,等等。

http://www.schibsted.pl/blog/back-end/refactoring /