跳转到内容

软件工程/测试/重构简介

来自维基教科书,开放世界中的开放书籍

代码重构是“重构代码的纪律方式”,[1]旨在改进软件的一些非功能性属性。通常,这是通过应用一系列“重构”来完成的,每个重构都是对计算机程序源代码的(通常是)微小的改变,不会改变其功能需求。优点包括改进代码可读性和降低复杂度以提高源代码的可维护性,以及更具表现力的内部架构或对象模型以提高可扩展性。

通过持续改进代码设计,我们让代码更容易使用。这与通常发生的情况形成鲜明对比:很少进行重构,而将大量注意力放在快速添加新功能上。如果你养成不断重构的习惯,你会发现扩展和维护代码更容易。

—- 乔舒亚·凯里夫斯基,重构到模式 [2]

重构并非在真空中进行,而是通常在为软件添加功能的背景下进行重构过程

  • "... 重构和添加新功能是两个不同的但互补的任务" -- 斯科特·安布勒

概述

[edit | edit source]

重构通常是由注意到代码异味而驱动的。[3]例如,手头的函数可能非常长,或者它可能与另一个附近的函数几乎完全相同。一旦识别出来,就可以通过重构源代码或将其转换为与以前行为相同但不再“有异味”的新形式来解决这些问题。对于一个长的例程,可以提取一个或多个更小的子例程。或者对于重复的例程,可以消除重复并使用一个共享的函数来代替它们。未能进行重构会导致积累技术债务。

重构活动有两大类益处。

  1. 可维护性。修复错误更容易,因为源代码易于阅读,并且作者的意图易于理解。[4]这可以通过将大型单片例程分解成一组单独的简明、命名清晰、单一用途的函数来实现。它可以通过将函数移动到更合适的类或删除误导性注释来实现。
  2. 可扩展性。如果应用程序使用可识别的设计模式,并且它提供了一些以前可能不存在的灵活性,那么扩展应用程序的功能更容易。[2]

在重构一段代码之前,需要一组可靠的自动单元测试。这些测试应该在几秒钟内[需要引用]证明模块的行为是正确的。然后,这个过程是一个反复循环,进行小的程序转换,对其进行测试以确保正确性,然后进行另一次小的转换。如果在任何时候测试失败,则撤消最后一次小的更改,并以不同的方式重新尝试。通过许多小的步骤,程序从它所在的位置移动到您想要它所在的位置。极限编程和其他敏捷方法的支持者将这种活动描述为软件开发周期的一个组成部分。

重构技术列表

[edit | edit source]

以下是一些代码重构的示例;其中一些可能只适用于某些语言或语言类型。在 Fowler 的 Refactoring 书籍[3]和 Fowler 的 Refactoring 网站[5]上可以找到更长的列表。

  • 允许更多抽象的技术
    • 封装字段 - 强制代码使用 getter 和 setter 方法访问字段
    • 泛化类型 - 创建更通用的类型以允许更多代码共享
    • 用状态/策略替换类型检查代码[6]
    • 用多态替换条件[7]
  • 将代码分解成更多逻辑部分的技术
    • 提取函数,将一个更大函数的一部分转换成一个新函数。通过将代码分解成更小的部分,更容易理解。这也适用于函数。
    • 提取类将代码的一部分从现有类移动到一个新的类。
  • 改进代码名称和位置的技术
    • 移动函数或移动字段 - 移动到更合适的类或源文件
    • 重命名函数或重命名字段 - 将名称更改为更能揭示其目的的新名称
    • 向上移动 - 在 OOP 中,移动到超类
    • 向下移动 - 在 OOP 中,移动到子类

硬件重构

[edit | edit source]

虽然术语重构最初专门指软件代码的重构,但在近年来,用硬件描述语言 (HDL) 编写的代码也被重构。术语硬件重构被用作重构硬件描述语言中代码的简称。由于 HDL 在大多数硬件工程师看来不被认为是编程语言,[8]硬件重构被认为是与传统代码重构不同的领域。

Zeng 和 Huss 提出了对模拟硬件描述(在 VHDL-AMS 中)进行自动重构的方法。[9]在他们的方法中,重构保留了硬件设计的仿真行为。改进的非功能性度量是重构后的代码可以由标准合成工具处理,而原始代码则无法处理。数字 HDL 的重构,尽管是手动重构,但也得到了 Synopsys 研究员 Mike Keating 的调查。[10][11]他的目标是使复杂系统更容易理解,从而提高设计师的生产力。

在 2008 年夏季,关于 VHDL 代码重构的激烈讨论出现在news://comp.lang.vhdl 新闻组上。[12]讨论围绕着一位工程师进行的特定手动重构,以及是否存在此类重构的自动化工具的问题。

截至 2009 年底,Sigasi 正在为 VHDL 重构提供自动化工具支持。[13]

历史

[edit | edit source]

过去,重构在开发流程中被避免。一个例子是 CVS(创建于 1984 年)不版本化文件和目录的移动或重命名。

虽然重构代码已经非正式地进行了多年,但 William Opdyke 1992 年的博士论文[14]是第一篇专门研究重构的论文,[15]尽管所有理论和机制长期以来一直作为程序转换系统可用。所有这些资源都提供了一个常见的重构方法目录;重构方法描述了如何应用该方法以及何时应该(或不应该)应用该方法的指标。

Martin Fowler 的著作《重构:改善既有代码的设计》[3] 是该领域的权威参考书。

"重构" 一词最早出现在 1990 年 9 月 William F. Opdyke 和 Ralph E. Johnson 发表的一篇文章中。 [16] Opdyke 的博士论文 [14] 于 1992 年出版,也使用了该术语。 [15]

"分解" 一词至少从 1980 年代初就在 Forth 社区中使用 [需要来源]。 Leo Brodie 的著作《思考 Forth》 (1984) 第六章专门讨论了这个主题。

在极限编程中,提取方法重构技术与 Forth 中的分解具有本质上相同的含义;将一个 "词" (或函数) 分解为更小、更易于维护的函数。

自动化代码重构

[编辑 | 编辑源代码]

许多软件编辑器和 IDE 都支持自动化重构。以下是其中一些编辑器或所谓的重构浏览器。

  • IntelliJ IDEA (用于 Java)
  • Eclipse 的 Java 开发工具包 (JDT)
  • NetBeans (用于 Java)
    • 以及 RefactoringNG,一个用于重构的 NetBeans 模块,您可以在其中编写程序抽象语法树的转换规则。
  • Embarcadero Delphi
  • Visual Studio (用于 .NET)
  • JustCode (Visual Studio 的插件)
  • ReSharper (Visual Studio 的插件)
  • Coderush (Visual Studio 的插件)
  • Visual Assist (Visual Studio 的插件,支持 VB、VB.NET、C# 和 C++ 的重构)
  • DMS 软件重构工具包 (为 C、C++、C#、COBOL、Java、PHP 和其他语言实现大规模重构)
  • Photran,一个用于 Eclipse IDE 的 Fortran 插件
  • SharpSort,Visual Studio 2008 的插件
  • Sigasi Studio - VHDL 和 System Verilog 的独立软件或插件软件
  • XCode
  • Smalltalk 重构浏览器 (用于 Smalltalk)
  • Simplifide (用于 Verilog、VHDL 和 SystemVerilog)
  • Tidier (用于 Erlang)

参考文献

[编辑 | 编辑源代码]
  1. Scott Ambler
  2. a b Kerievsky, Joshua (2004). Refactoring to Patterns. Addison Wesley.
  3. a b c Fowler, Martin (1999). Refactoring: Improving the design of existing code. Addison Wesley.
  4. Martin, Robert (2009). Clean Code. Prentice Hall.
  5. Fowler 重构网站上的重构技术
  6. 用状态/策略替换类型检查代码
  7. 用多态性替换条件语句
  8. 硬件描述语言和编程语言
  9. Kaiping Zeng, Sorin A. Huss, "通过行为 VHDL-AMS 模型的代码重构进行架构细化"。ISCAS 2006
  10. M. Keating :"复杂性、抽象和复杂系统设计挑战",在 DAC'08 教程 [1]"弥合验证差距:从 C++ 到 RTL 的实际设计"
  11. M. Keating, P. Bricaud: 系统级芯片设计的复用方法手册,Kluwer Academic Publishers,1999。
  12. http://newsgroups.derkeiler.com/Archive/Comp/comp.lang.vhdl/2008-06/msg00173.html
  13. www.eetimes.com/news/latest/showArticle.jhtml?articleID=222001855
  14. a b Opdyke, William F (1992). "重构面向对象的框架" (压缩 Postscript). 博士论文. 伊利诺伊大学厄巴纳-香槟分校. 检索于 2008-02-12. {{cite journal}}: Cite journal requires |journal= (帮助); Unknown parameter |month= ignored (帮助)
  15. a b Martin Fowler,"MF Bliki:重构词源"
  16. Opdyke,William F.;Johnson,Ralph E. (1990 年 9 月). "重构:一种设计应用程序框架和改进面向对象系统的方法". 面向对象编程研讨会论文集,重点关注实际应用 (SOOPPA). ACM. 

进一步阅读

[编辑 | 编辑源代码]
[编辑 | 编辑源代码]
华夏公益教科书