【代码范式集】:使用 “IDE 重构” 改善代码质量

重构是改善代码质量的重要手段,依赖于单元测试和可测试代码。本文聚焦于在缺乏测试的情况下,如何利用IDE重构功能进行代码优化。IDE重构通过快捷键触发,自然融入日常开发,降低犯错成本,尤其适合初学者。尽管IDE重构能力有限,但仍是快速改进代码质量的有效工具。介绍了IDE如IntelliJ IDEA的重构功能,并提到了编辑器如Visual Studio Code的重构插件。
摘要由CSDN通过智能技术生成

重构,指对软件代码做任何更动,以增加可读性或者简化结构,而不影响输出结果。可是我们要如何才能不影响输出结果呢???答案是:测试。测试的意义在于对输出结果进行测试,用于保障现有代码的功能是正常的。一旦我们修改了代码,导致测试失败了,那我们就知道哪里改错了。


640?wx_fmt=jpeg


因此重构依赖于单元测试和可测试的代码(即短小、可 mock 的代码)。在重构之前,对应的代码拥有测试是信心的保证。可由于种种情况,我们的代码中不存在测试,我们就放弃代码重构吗?

所以,这篇文章讲述地是,如何在不包含测试的情况下,来对代码进行重构——IDE 重构。需要注意的是,IDE 重构在大部分的情况下是不会影响输出结果的,但是在极少数的情况下可能会影响结果——比如 IDE 出 bug 了。hiahiahiahia~

范式:IDE 重构

IDE 重构,即借助于 IDE 来对代码进行重构,其通常是由快捷键来触发。它将重构的主要工作交给 IDE,而不是由开发人员痛苦的修改代码来完成。多数时候,我们只需要按下快速键,再输入一些必要的名称、参数,重构就完成了。因此,它是每天我们的开发中,不可获缺的一部分。可以随时随地进行,而不需要预留一个专用的重构时间。

自然而然发生

640?wx_fmt=jpeg

那些,我们视为腐烂的代码,并不是在第一天就如此。在最初设计的时候,它们往往有着好的代码结构,良好的设计规范。只是随着时间的推移,业务不断地增加,代码量便不断地增加,缺乏有效的代码改善机制,便会使得代码腐烂。但是,我们也不能提前对代码进行重构,那样的话就是过度设计。

重构,有时在编写代码的过程中,自然而然发生的。而 IDE 重构则是,编写代码的过程中,看到可以重构的地方,按下IDE 的快速键,迅速地完成战斗。

因此,就这种角度来看,IDE 重构是自然而然发生的,它应该作为日常开发的一部分,而不是额外的花费时间进行重构。在这一点上,也普通的代码重构是不同的。普通的代码重构,是我们看到之前的代码写得不符合规范、设计,便进一步地想去改善质量。往往,我们也会将这处重构,放置在完成功能之后进行。

值得注意的是IDE 重构所能做的内容有限,远不及常规重构的范围来得广泛。

如下是微前端 Mooa 框架中,最初某个函数的代码的一部分:

 
 
  1. customEvent('mooa.routing.change', {

  2.  url: eventArguments.url,

  3.  app: activeApp['appConfig']

  4. })

而随着业务的演进,代码便进一步便得复杂:

 
 
  1. if (activeApp.mode === 'iframe') {

  2.  ...

  3.  if (iframeEl && iframeEl.contentWindow) {

  4.  ...

  5.  contentWindow.dispatchEvent(customEvent(MOOA_EVENT.ROUTING_CHANGE, eventArgs))

  6.  }

  7. } else {

  8.  customEvent(MOOA_EVENT.ROUTING_CHANGE, eventArgs)

  9. }

一旦,我们添加了一个新的条件,我们的代码会进一步复杂化。而在那之前,对于 if 语句而言,我的做法是什么也不做,因为无法预料它的演变。一来,这样的 if 语句没有多少演进的方式,提供重构成多态则进一步复杂代码。二来,当遇到新的需求变更时,原先的重构可能等于白做,甚至于会影响我们下一步的编程。

不过,在上述的过程中,我做了两件事:

  • 提取了公有的变量

  • 提取了公有的参数

而这些都可以通过 IDE 的提取变量的快捷键来完成。

从容不迫应对

640?wx_fmt=jpeg

由于 IDE 重构,更多的是依赖于工具,而不是依赖于编程经验。它可以为年轻(编程经验少)的程序员,带来一定的信心,使得他/她们开始敢去重构代码。你可能也会担心,它带好一个不好的习惯,即在不编写测试的时候,进行代码重构。所以,它看上去像是一把双刃剑。但是,在我的想法来看,只要能开始去改变,那就是一个好的开始。每个老年(资深)程序员,都是从一个坑过去的,要不就不是资深的程序员。

换句话来说,当你遇到一个棘手的问题,而有一个资深的程序员,快速地帮你解决了问题,说明他/她也走过这个坑。比如,你应对一个 git 冲突的时候,可能会束手无策,哪怕你对 SVN 再熟悉,你也要面对这种变化。这样的问题解决多了,也就有经验了。这种方式和 IDE 重构一样,都只是使用工具而已。

即使都是使用工具,就只是工具的熟悉程度与否。练习,多加练习,然后掌握 IDE 重构,迈出了第一步。再向前,你就开始走向真正的重构了。

最小犯错成本

640?wx_fmt=jpeg

虽然说是使用 IDE 进行重构,但是在复杂的情况下,它可能还是会出错。因此,进行任何的重构之前,我们都需要打造一个安全的环境——至少,将要重构的代码应该在本地进行提交,又或者提交到服务端。它相当于我们在完成了业务功能之后,进行一系列小的修改。

即它意味着,我们可以在一个安全的时间里提交代码,又意味着哪怕是重构失败,我们也可以回退。诸如 Git 这种支持本地提交的代码版本管理工具,大概是我见过最好的减少犯错成本的工具。不论,我对本地的代码库做怎样的修改,都可以从远程获取原来的代码。

事实上,不止于还需要提供一个安全的团队环境(政治环境),即让程序员能花时间去改善代码。但是,这种重构需要存在时间的限制。

  • 如果你花关天、一天、两天的时间,要对之前一个月的代码重构,那么并不存在问题——业务在不断叠加,每隔一段时间都会出现代码、架构上的问题。这个时候的抢救,能及时把设计正确的方式。再往后推移,可能会影响整个系统的架构,成功地实现了 “千里之堤,溃于蚁穴”。

  • 如果一处代码的重构,需要花费四五天的时间,那么就需要正视这个问题。它不是一个小问题,可能存在多个问题。对它的重构和改善,往往需要和团队里的资深程序员一起讨论。

对于重构来说,新手程序员更加需要适当地鼓励,辅以合适的技术培训,或者进行手把手的结对编程。

缺点:有限的代码质量改善

640?wx_fmt=jpeg

让我们再强迫一遍:

  • IDE 重构是一种有限的代码质量改善

  • IDE 重构是一种有限的代码质量改善

  • IDE 重构是一种有限的代码质量改善

它只是一种快速的重构方式,对于复杂的代码结构来说,往往是无能无力的。

 
 
  1. function openFile(willLoadFile: string, isTempFile: boolean = false) {

  2.  let imageRegex = /\.(jpe?g|png|gif|bmp|ico)$/i;

  3.  let htmlRegex = /\.(html)$/i;

  4.  let wordRegex = /\.(doc?x)$/i;


  5.  if (imageRegex.test(willLoadFile)) {

  6.  return mainWindow.previewFile(willLoadFile);

  7.  } else if (htmlRegex.test(willLoadFile)) {

  8.  return openHtmlPage(BrowserWindow, willLoadFile);

  9.  } else if (wordRegex.test(willLoadFile)) {

  10.  return shell.openItem(willLoadFile);

  11.  }

  12. }

不过,要对于这一种类似的 if 语句来说,换成 switch 语句并没有改善多少可读性。

这个时候,我们可能会考虑换成多态,这样便需要依赖于手动进行重构——需要依赖于测试。但是多态,又可能进一步复杂化代码——行数和类变得更多了。

工具

既然,本文的标题是 IDE 重构,但是它应该是叫工具重构。主要是笔者,懒,懒得配置编辑器,所以就习惯使用了 IDE。要怪就怪我司,给程序员配了 IDE。

IDE

大量的 IDE 支持重构功能,打开你最常使用的工具,你也会发现:咦,我的 IDE 也有这样的功能。如 Jetbrians 家的 Intellij IDEA 对于静态类型语言,如 Java 的支持就更好了:

640?wx_fmt=png

Intellij IDEA

如上图所示,其拥有大量地可用的重构功能。反正都是交了信仰费的人,不掌握好工具,对不起自己的辛辛苦苦的码字。

Editor + 重构插件

现在的,普通的编辑器,也拥有这样的重构功能,如 Visual Studio Code 便自带了一些。哪怕是诸如 Vim 这种原始的 IDE,加上对应的重构插件,也可以完成相应功能。如在 Visual Studio Code 中提供了一些对应的重构功能。其中比较常用的有:

  • 提取变量

  • 提取方法

  • 重命名

640?wx_fmt=gif

TypeScript 提取变量

诸如 JavaScript 这一类的动态语言,则会应了那句话:“动态类型一时爽,代码重构火葬场”。因为各式的智能提示,都依赖于对语言的静态类型检查,但是动态类型往往很难实现这一点。使用 TypeScript 对于可维护的代码是一个可好的选择。

示例

相关的内容,可以看我之前录的视频:https://v.youku.com/vshow/idXMTI2NjQ0NDAxMg==.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值