美文网首页
重构技巧-提炼函数

重构技巧-提炼函数

作者: 还仙 | 来源:发表于2019-10-15 14:02 被阅读0次

这是《重构-改善既有代码的设计》这本书的原文

动机

  提炼函数是我最常用的重构之一。(在这儿我用了“函数/function”这个词,但换成面向对象语言中的“方法/method”,或者其他任何形式的“过程/procedure”或者“子程序/sybroutine”,也同样适用)我会浏览一段代码,理解其作用,然后将其提炼到一个独立的函数中,并以这段代码的用途为这个函数命名。

    对于“何时应该把代码放进独立的函数”这个为题,我曾经听过多种不同的意见,有的观点从代码的长度考虑,认为一个函数应该能在一屏中显示。有的观点从复用的角度考虑,认为只要被用过不止一次的代码,就应该单独放进一个函数;只用过一次的代码则保持内联(inline)的状态。但我认为最合理的观点是“将意图与实现分开”:如果你需要花时间浏览一段代码才能弄清楚它到底在干什么,那么就应该将其提炼到一个函数中,并根据他所做的事为其命名,以后再读到这段代码时,你一眼就能看到函数的用途,大多数的时候根本不需要关心函数如何达成其用途(这是函数体内干的事)。

    一旦接受了这个原则,我就逐渐养成一个习惯:写非常小的函数----通常只有几行的长度。在我看来,一个函数一段超过六行,就开始散发臭味。我甚至经常会写一些只有一行代码的函数。Kent beck曾向我展示最初的Smalltalk系统中的一个例子,从那时起我就接受了“函数名的长度不重要”的观念。那时运行Smalltalk的计算机只有黑白屏显示器,如果你想高亮凸显默写文本或图像,就需要翻转视频的现实。为此,Smalltalk用于控制图像显示的类有一个叫做highlight的方法,其中的实现就只是调用reverse方法。在这个例子里,highlight方法的名字比实现还长,但这并不重要,因为在这个方法中,代码的意图与实现之间有着相当大的差距。

    有些人担心段函数会造成大量函数调用,因而影响性能。在我尚且年轻时,有时确实会有这个问题;但如今“由于函数调用影响性能”的情况已经非常罕见了。短函数常常能让编译器的优化功能运转更良好,因为段函数可以更容易地被缓存。所以,应该始终遵循性能优化的一般指导方针,不用过早担心性能问题。

    小函数得有个好名字才行,所以你必须在命名上花心思。起好名字需要练习,不过一旦你掌握了其中的技巧,就能写出很有自描述性的代码。

    我经常会看见这样的情况: 在一个大函数中,一段代码的顶上放着一句注释,说明这段代码要做什么。在把这段代码提炼到自己的函数中时,这样的注释往往会提示一个好名字。

做法

    创造一个新函数,根据这个函数的意图来对它命名(以它“做什么”来命名,而不是以它“怎么做”命名)。                         

              如果想要提炼的代码非常简单,例如只要新函数的名称能够以更好的方式昭示代码意图,我还是会提炼它。不过,我不一定非得马上想出最好的名字,有时在提炼的过程中好的名字才会出现。有时我会提炼一个函数,尝试使用它,然后发现不太合适,再把它内联回去,这完全没问题。只要在这个过程中学到了东西,我的时间就没有白费。

    如果编程语言支持潜逃函数,就把新函数嵌套在源函数里,这能减少后面需要处理的超出作用于的变量个数。我可以稍后再使用《搬移函数》把它从源函数中搬移出去。

    将带提炼的代码从源函数复制到新建的目标函数中。

仔细检查提炼出的代码,看看其中是否引用了作用于限于源函数、在提炼出的新函数中访问不到的变量。若是,一参数形式将它们传递给新函数。

              如果提炼出的新函数嵌套在源函数的内部,就不存在变量作用于的问题了。

              这些“作用域限于源函数”的变量通常是局部变量或者源函数的参数。最通用的做法是将它们都作为参数传递给新          函数。只要没有提炼部分对这些变量赋值,处理起来就没有什么难度。

              如果某个变量是在提炼部分之外声明但只在提炼部分被使用,就把变量声明也搬移到提炼部分代码中去。

            如果变量按照传递给提炼部分又在提炼部分被赋值,就必须多加小心。如果只有一个这样的变量,我会尝试将提炼出的新函数变成一个查询,用其返回值给该变量赋值。

            但有时在提炼部分被赋值的局部变量太多,这是最好先放弃提炼。这种情况下,我会考虑先使用别的重构手法,例如拆分变量或者以查询取代临时变量,来简化变量的使用情况,然后再考虑提炼函数。

所有变量都处理完之后,编译。

如果编程语言支持编译期检查的话,在处理完所有变量之后再做一次编译是很有用的,编译器经常会帮你找到没有被恰当处理的变量。

在源函数中,将被提炼代码段替换为对目标函数的调用。

测试。

查看其他代码是否有与被提炼的代码段相同或者相似之处。如果有,考虑使用以函数调用取代内联代码令其调用提炼出的新函数。

有些重构工具直接支持这一步。如果工具不支持,可以快速搜索一下,看看别处是否还有重复代码。

相关文章

  • 重构技巧-提炼函数

    这是《重构-改善既有代码的设计》这本书的原文 动机 提炼函数是我最常用的重构之一。(在这儿我用了“函数/func...

  • 重构技巧-提炼函数

    这是《重构-改善既有代码的设计》这本书的原文 动机 提炼函数是我最常用的重构之一。(在这儿我用了“函数/f...

  • 001-重新组织函数

    重新组织函数 重构的基本技巧:小步前进,频繁测试 1. Extract Method(提炼函数) Q:你有一段代码...

  • 重构读书笔记-6_8总结

    重构第六章 总结 重构方法 1.Extract Method(提炼函数): 将一段代码提炼成为一个函数2.Inli...

  • 优化代码的几个小技巧

    前言 最近看了《重构-改善既有代码的设计》这本书,总结了优化代码的几个小技巧,给大家分享一下。 提炼函数(适当抽取...

  • 重构读书笔记——重新组织函数

    Extract Method 提炼方法 动机 Extract Method 是最常用的重构手法之一。 函数过长或者...

  • 重构-重新组织函数

    引言 对付过长函数,一项重要的重构首发就是Extract Method(提炼函数),它把一段代码从原先函数中提取出...

  • 重构(四) -- 提炼函数(Extract Method)

    含义 将一段代码组织在一起并放进一个独立函数,并让函数名称解释该函数的用途 简单例子 上面例子中将两句打印信息的代...

  • 代码重构和编程技巧笔记

    具体是否需要重构,以及如何进行重构,这需要根据系统的类型、项目工期、人力等外界因素一起决定。 1、提炼函数 避免出...

  • 重构的技巧

    重构的技巧 重构的技巧

网友评论

      本文标题:重构技巧-提炼函数

      本文链接:https://www.haomeiwen.com/subject/vkksmctx.html