ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
### Long Method(过长函数) 拥有[短函数」(short methods)的对象会活得比较好、比较长。不熟悉面向对象技术的人,常常觉得对象程序中只有无穷无尽的delegation(委托),根本没有进行任何计算。和此类程序共同生活数年之后,你才会知道,这些小小函数有多大价值。「间接层」所能带来的全部利益——解释能力、共享能力、选择能力——都是由小型函数支持的(请看p.61的「闯接层和重构」〕。 很久以前程序员就巳认识到:程序愈长愈难理解。早期的编程语言中,「子程序调用动作」需要额外开销,这使得人们不太乐意使用small method。现代OO语言几乎已经完全免除了进程(process)内的「函数调用动作额外开销」。不过代码阅读者还是得多费力气,因为他必须经常转换上下文去看看子程序做了什么。某些开发环境允许用户同时看到两个函数,这可以帮助你省去部分麻烦,但是让small method容易理解的真正关键在于一个好名字。如果你能给函数起个好名字,读者就可以通过名字了解函数的作用,根本不必去看其中写了些什么。 最终的效果是:你应该更积极进取地分解函数。我们遵循这样一条原则:每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立函数中,并以其用途(而非实现手法)命名。我们可以对一组或甚至短短一行代码做这件事。哪怕替换后的函数调用动作比函数自身还长,只要函数名称能够解释其用途,我们也该毫不犹豫地那么做。关键不在于函数的长度,而在于函数「做什么」和「如何做」之间的语义距离。 百分之九十九的场合里,要把函数变小,只需使用Extract Method。找到函数中适合集在一起的部分,将它们提炼出来形成一个新函数。 如果函数内有大量的参数和临时变量,它们会对你的函数提炼形成阻碍。如果你尝试运用Extract Method,最终就会把许多这些参数和临时变量当作参数,传递给被提炼出来的新函数,导致可读性几乎没有任何提升。啊是的,你可以经常运用Replace Temp with Query 来消除这些暂时元素。Introduce Parameter Object 和Preserve Whole Object 则可以将过长的参数列变得更简洁一些。 如果你已经这么做了,仍然有太多临时变量和参数,那就应该使出我们的杀手锏: Replace Method with Method Object。 如何确定该提炼哪一段代码昵? 一个很好的技巧是:寻找注释。它们通常是指出「代码用途和实现手法间的语义距离」的信号。如果代码前方有一行注释,就是在提醒 你:可以将这段代码替换成一个函数,而且可以在注释的基础上给这个函数命名。就算只有一行代码,如果它需要以注释来说明,那也值得将它提炼到独立函数去。 条件式和循环常常也是提炼的信号。你可以使用Decompose Conditional 处理条件式。至于循环,你应该将循环和其内的代码提炼到一个独立函数中。