提炼函数Extract Function:将代码提炼到函数中。
- 动机:“将意图与实现分开”:如果你需要花时间浏览一段代码才能弄清它在干什么,那么就应该将其提炼到一个函数中,并根据它所做的事为其命名。以后再读到这段代码时,你一眼就能看到函数的用途,大多数时候根本不需要关心函数如何达成其用途(这是函数体内干的事)。
- 新函数命名:以它“做什么”来命名,而不是以它“怎样做”命名。
内联函数inline Function:提炼函数的反向重构。
- 动机:函数间调用时,简介层过度简单,过度运用。a->b b->c c->d. a->d。那么去掉中间层,直接调用函数本体。
提炼变量Extract Variable:提炼变量。
- 使用:
- 在方法内,抽取成单独的表达式
- 在类内,判断可否将单独的表达式提取函数
内联变量Inline Variable:提炼变量的反向重构。
- 动机:在一个函数内部,变量能给表达式提供有意义的名字,因此通常变量事好东西。但有时候,这个名字并不比表达式更具表现力。还有些时候,变量可能会妨碍重构附近的代码。若果真如此,就应该通过内联的手法消除变量
改变函数声明Change Function Declaration:用于修改函数的名字,或者添加删减参数。
- 包含情形:
- 函数和参数改名:好的名字更易理解。
- 函数参数的增减,让参数列表更适合其上下文。
封装变量 Encapsulate Variable。
- 动机:如果数据的可访问范围很大,一旦对改数据进行变化,那么所有引用该数据的代码都需要同时修改。这就类似于全局数据的修改。
- 做法:
- 创建封装函数,在其中访问和更新变量值。将对变量的引用改为对函数的调用。
- 因为在改名或搬移函数的过程中,总是可以比较容易地保留旧函数作为转发函数(即旧代码调用旧函数,旧函数再调用新函数)。
变量改名Rename Variable:改变变量名字。
- 动机:好的名字使得程序更易理解。
引入参数对象Introduce Parameter Object:把常在一起出没的参数组合成一个对象。
- 动机:数据项之间的关系变得明晰,组织成一个统一的数据结构,今后数据项的增减,在调用处不需作出改变。再就是调用处的参数列表缩短,
函数组合成类Combine Functions into Class:把函数和它们操作的数据一起组合成类。
- 动机:如果发现一组函数形影不离地操作同一块数据(通常是将这块数据作为参数传递进函数),我就认为,是时候组件一个类了。类能明确地给这些函数提供一个共用的环境,在对象内部调用这些函数可以少穿许多参数,从而简化函数调用,并且这样一个对象也可以更方便地传递给系统的其他部分。
函数组合成变换Combine Functions into Transform:将函数组合成变换式,这对于处理只读数据尤为便利。
- 动机:在软件中,经常需要把数据“喂”给一个程序,让它再计算出各种派生信息。这些派生数值可能会在几个不同地方用到,因此这些计算逻辑也常会在用到派生数据的地方重复。我更愿意把所有计算派生数据的逻辑收拢到一处,这样始终可以在固定的地方找到和更新这些逻辑,避免到处重复。一个方式是采用数据变换函数:这种函数接受源数据作为输入,计算出所有的派生数据,将派生数据以字段形式填入输出数据。有了变换函数,我就始终只需要到变换函数中去检查计算派生数据的逻辑。
拆分阶段Split Phase:将模块组成界限分明的处理阶段。
- 动机:每当看见一段代码在同时处理两件不同的事,我就想把它拆分成个字独立的模块,因为这样到了需要修改的时候,我就可以单独处理每个主题,而不必同时在脑子里考虑两个不同的主题。如果运气够好的话,我可能只需要修改其中一个模块,完全不用回忆起另一个模块的诸般细节。
- 做法:最简单的拆分方法之一,就是把一大段行为分成顺序执行的两个阶段。可能你有一段处理逻辑,其输入数据的格式不符合计算逻辑的要求,所以你得先对输入数据做一番调整,使其便于处理。也可能是你把数据处理逻辑分成顺序执行的多个步骤,每个步骤负责的任务全然不同。