重构第六章-重新组织函数
6.1 Extract Method(提炼函数)
你有一段代码可以被组织在一起并独立出来。将这段代码放进一个独立函数中,并让函数名称解释该函数的用途。
动机:
如果每个函数的粒度都很小,那么函数被复用的机会就更大;这会使高层函数读起来就像一系列注释;如果函数都是细粒度,那么函数的覆写也会更容易些。
做法:
创造一个新函数,根据这个函数的意图来对它命名(以它做什么来命名,而不是以它怎样做命名)。
将提炼出的代码从源函数复制到新建的目标函数中。
仔细检查提炼出的代码,看看其中是否引用了“作用域限于源函数”的变量(包括局部变量和源函数变量)
检查是否有“仅用于被提炼代码段”的临时变量。如果有,在目标函数中将它们声明为临时变量。
检查被提炼代码段,看看是否有任何局部变量的值被他改变。
检查被提炼代码段,看看是否有任何局部变量的值被它改变。如果一个临时变量值被修改了,看看是否可以将被提炼代码段处理为一个查询,并将结果赋值给相关变量。
将被提炼代码段中须要读取段局部变量,当作参数传给目标函数。
处理完所有局部变量之后,进行编译。
在源程序中,将被提炼代码段替换为对目标函数的调用。
编译,测试。
6.2 Inline Method(内联函数)
一个函数的本体与名称同样清楚易懂。在函数调用点插入函数本体,然后移除该函数。
动机:
有的函数内部代码和函数名称同样清晰易读。
有一群不合理的函数,先内联再提炼。
做法:
检查函数,确定它不具多态性。
找出这个函数的所有被调用点。
将这个函数的所有被调用点都替换为函数本体
编译测试
删除该函数的定义
6.3 Inline Temp(内联临时变量)
你有一个临时变量,只被一个简单表达式赋值一次,而它妨碍了其他重构手法。将所有对该变量的引用动作,替换为对它赋值的那个表达式自身。
动机:
你发现某个临时变量被赋予某个函数调用的返回值。
做法:
检查给临时变量赋值的语句,确保等号右边的表达式没有副作用。
如果这个临时变量并未被声明为final,那就将它声明为final,然后编译。
找到该临时变量的所有引用点,将它们替换为“为临时变量赋值”的表达式。
每次修改后,编译并测试。
修改为所有引用点之后,删除该临时变量的声明和赋值语句。
编译,测试。
6.4 Replace Temp with Query(以查询取代临时变量)
你的程序以一个临时变量保存某一表达式的运算结果。将这个表达式提炼到一个独立函数中。将这个临时变量的所有引用点替换为对新函数的调用。此后,新函数就可以被其他函数使用。
动机:
临时变量的问题在于,它们是暂时的,而且只能在所属函数内使用。由于临时变量只在所属函数内可见,所以他们会驱使你写出更长的函数,因为这样才能访问到需要的临时变量。
做法:
找出只被赋值一次的临时变量。
将该临时变量声明为final。
编译。
将“对该临时变量赋值”之语句的等号右侧部分提炼到一个独立函数中。
编译,测试。
在该临时变量身上实施Inline Temp。
6.5 Introduce ExplainingVariable(引入解释性变量)
你有一个复杂的表达式。将该复杂表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途。
动机:
表达式有可能非常复杂而难以阅读。这种情况下,临时变量可以帮助你将表达式分解为比较容易管理的形式。
做法:
声明一个final临时变量,将待分解之复杂表达式中的一部分动作的运算结果赋值给它。
将表达式中的“运算结果”这一部分,替换为上述临时变量。
编译,测试。
重复上述过程,处理表达式的其他部分。
6.6 Split Temporary Variable(分解临时变量)
你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。针对每次赋值,创造一个独立、对应的临时变量。
动机:
如果临时变量承担多个责任,它就应该被替换(分解)为多个临时变量,每个变量只承担一个责任。
做法:
在待分解临时变量的声明及其第一次被赋值处,修改其名称
将新的临时变量声明为final。
以该临时变量的第二次赋值动作为界,修改此前对该临时变量的所有引用点,让它们引用新的临时变量。
在第二次赋值处,重新声明原先那个临时变量。
编译,测试。
逐次重复上次过程。每次都在声明处对临时变量改名,并修改下次赋值前的引用点。
6.7 Remove Assignments to Parameters(移除对参数的赋值)
代码对一个参数进行赋值。以一个临时变量取代该参数的位置。
6.8 Replace Method with Method Object(以函数对象取代函数)
你有一个大型函数,其中对局部变量的使用使你无法采用Extract Method。将这个函数放进一个单独对象中,如此依一来,局部变量就成了对内的字段。然后可以在同一个对象中将这个大型函数分解为多个小型函数。
6.9 Substitute Algorithm(替换算法)
你想要把某个算法替换为另一个更清晰的算法。
将函数本体替换为另一个算法。
参考资料:
《重构-改善既有代码的设计》