什么是代码重构?

栏目:影视资讯  时间:2022-11-07
手机版

  重构是软件开发中最常用的术语之一,几十年来在软件维护中一直发挥着重要作用。虽然大多数开发人员对重构过程都有直观的了解,但我们许多人对这项重要技能缺乏真正的掌握。在本文中,我们将探讨重构的教科书定义,该定义如何适应软件开发的实际情况以及如何确保我们的代码库已为重构做好准备。在此过程中,我们将从头到尾逐步进行一整套重构,以说明此无处不在的过程的简单性和重要性。

  一个简单的定义

  重构是软件开发中最不言而喻的过程之一,但令人惊讶的是,它很难正确执行。在大多数情况下,我们会偏离严格的重构,而对过程进行近似处理;有时,事情会解决,我们剩下的代码会更整洁,但有时,我们陷入困境,想知道哪里出了问题。无论哪种情况,重要的是要充分了解准系统重构的重要性和简单性。关于该主题的开创性著作的作者Martin Fowler 对重构的定义如下:

  重构是一种用于改进现有代码库设计的受控技术。它的本质是应用一系列小的行为保留转换,每个转换“都太小而不值得做”。但是,每个转换的累积效果都非常显着。通过分步进行,可以降低引入错误的风险。您还可以避免在进行重组时损坏系统,这使您可以在较长的时间内逐步重构系统。

  简而言之,重构过程涉及一些小的,可管理的步骤,这些步骤逐渐增加了代码的清洁度,同时仍保持了代码的功能。随着我们对这些小更改的执行越来越多,我们开始将凌乱的代码转换为更简单,更易于阅读和更易于维护的代码。进行更改的不是一个单一的重构:朝着一个单一目标执行的许多小型重构的累积效果才有所不同。

  例如,如果要简化方法,则重命名单个变量对大型方法主体可能没有什么影响,但是如果重命名此变量,我们发现另一个变量表示相同的值,则可以删除重复的变量。这从方法中删除了一行,这看似微不足道,但是随着我们继续该过程,越来越多的行被删除,方法主体开始缩小。在某些情况下,方法可能缩小到如此微不足道的水平,以至于我们用方法主体本身来代替对方法的调用(称为内联)。

  当我们删除该方法时,我们可能会意识到包含该方法的类可能很小,因此不再需要将其逻辑放在单独的类中。然后,我们移动其余方法更改为更合适的班级并删除原始班级。通过简单地更改变量名并减少重复,重构过程便迅速发展为方法的删除,最终是类的删除。重要的是要注意,在整个过程中,我们从未更改过应用程序的外部可见行为:我们只是转移了逻辑并删除了重复项,但是应用程序继续像开始重构过程之前那样运行。下图在视觉上将这一过程与显着的变化进行了对比,这些显着的变化以一次大的动作对代码进行了重大更改。

  标准重构技术

  从这个意义上讲,重构类似于攀岩。我们从地面开始,找到一个牢牢抓住的地方。接下来,我们加强并检查我们的立足点。然后,我们找到了一个新的抓地力,动手并脚动,将自己置于岩壁上方。在每一步中,我们先测试立足点,然后再移至下一个位置。虽然与岩壁数百英尺相比,我们每进步几英尺似乎微不足道,但每一步都使我们比上一步高了几英尺。一段时间后,我们往下看,发现我们已经沿着岩壁行进了一段距离。

  与攀岩一样,有一组标准的技术可用于安全有效地完成手头的任务。在重构中,这些过程称为重构技术,目前有这些技术的标准目录。众所周知,这些技术中的每一种都可以执行安全的代码转换,其中系统的行为不变,但是提高了代码的可读性或简单性。这些技术的全面清单,包括一些非常有用的信息,可以在Martin Fowler的Refactoring中找到。这些重构技术也已收集到一个名为Refactoring Guru的交互式网站中。。强烈建议读者使自己熟悉这些技术,因为它们构成了重构的词汇。例如,通常会听到开发人员的状态,即他或她将“内联”方法或“拉入”层次结构中的方法或字段。

  取得进展

  重要的是要理解,重构不是西西弗斯式的努力:隧道尽头有亮光。尽管在成千上万,数十万甚至数百万行的代码库中删除一行似乎是徒劳的,但事实并非如此。就像系统一次建立一行一样,它可以一次清理一行,一个变量,一个方法和一个类。由于重构似乎从未真正完成,因此似乎是徒劳的,但是与西西弗斯不同,我们从一开始就没有注定要失败,也没有诅咒永远不会取得进展。它需要一定程度的耐心,以及一些重要的先决条件。

  先决条件

  并非每个代码库都可以重构。尽管可以清除任何代码,但是只能真正重构特定的代码库。为了执行此过程,我们必须具备两个先决条件:(1)目标和(2)快速,自动化的测试。

  一个目标

  重构时,我们需要牢记目标。这个目标不必太复杂或什至太大,但是我们需要有一些标准来知道何时充分重构了代码。例如,我们可能具有非常复杂的类层次结构,具有不需要的接口,抽象类和具体实现的级别。我们针对此层次结构的目标可以是将类的数量减少到一些可管理的数量。我们可以通过移动方式实现这一目标向上和向下的层次结构,组成类,而不是继承他们,以及其他主机推广技术。

  建立目标时要记住的一些技巧包括:

  · 保持简单:从小处着手,并专注于合理大小的目标

  · 分解大目标:如果一个目标涉及一次重构数百个类,则将该目标分解为小块;选择较小的类子集进行重构;在此子集上完成重构后,移至另一个子集

  · 明确:不要陷入说目标是“整理方法”或“清理类”(模糊目标和抽象目标)的陷阱;而是设置一个更可衡量的目标,例如删除嵌套循环,删除复杂的条件,通过将公共代码移入私有方法来减少方法的行数等。

  · 专注于最终目标:不要为达成目标所需的中间步骤而分心;如果减少继承层次结构需要创建一些类并删除其他类,请不要陷入困境,而忘了最终目标是重构层次结构,而不是简单地添加和删除类

  尽管在代码库中总是有更多可重构的内容,但从小处着手并取得进展。完成少量的重构可以使我们获得一定的信心和满意度。有了目标,我们现在可以提供重构的技术要求:快速和自动化的测试。

  自动化测试

  在进行重构过程时,我们可以问自己的两个最重要的问题是:

  1. 系统的期望行为是什么?

  2. 我们如何知道在进行更改时它将保持一致?

  这两个问题都可以通过测试来回答。从理论上讲,每次我们对系统进行很小的更改时,唯一可以知道系统预期的行为并且知道我们没有更改的唯一方法就是对代码运行一组测试。用务实的话来说,我们需要这个测试套件快速执行,并为我们提供一个简单的是或否的答案:问题是否还在按预期进行?在现实世界的应用程序中,这意味着可以快速,自动化地测试,从而充分发挥系统的性能。总之,我们的测试必须具有以下特征,以便我们重构代码:

  · 快速执行

  · 提供全面覆盖

  · 如果显示正确的系统行为则通过,否则失败

  很难完全定义完整的覆盖范围,但是它涵盖了与应用程序相关的所有单元,集成,验收,性能和压力测试,或者涉及重构的应用程序部分。这些测试必须快速运行,这很重要,因为我们必须相对迅速地获得反馈,以使我们的重构卓有成效。如果测试需要很长时间才能运行,那么每次进行更改时都不太可能运行它们。例如,如果我们正在执行小的重构,每个重构大约需要15秒才能完成,而测试套件则需要10分钟才能运行,所以在每次重构之后我们不太可能会运行整个测试套件。请注意,并非需要运行应用程序中的每个测试(例如,对系统的不相关部分进行长时间的验收测试),

  这些测试使我们知道,所做的任何更改都不会改变系统的行为。通过使用这些测试,我们可以系统地执行重构循环,而不必担心会破坏系统。这个周期始于我们进行更改,运行测试并查看测试是否通过。如果这样做,我们可以放心,我们的重构不会对系统造成不利影响,并继续进行另一次重构。如果测试失败,我们知道我们已经以某种外部可见的方式更改了系统,并且应该撤消我们的更改(实际上,这不是重构,因为它改变了系统的外部行为)。

  最后,开发这么多年我也总结了一套学习Java的资料与面试题,如果你在技术上面想提升自己的话,可以关注我,私信发送领取资料或者在评论区留下自己的联系方式,有时间记得帮我点下转发让跟多的人看到哦。

  举报/反馈

上一篇:《蜘蛛侠:英雄远征》:你离开了世间,从此没有人陪我说话
下一篇:21岁CUBA前锋志在CBA,身体素质劲爆模板易建联

最近更新影视资讯