重构第六章-重新组织函数

 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(替换算法)

你想要把某个算法替换为另一个更清晰的算法。

将函数本体替换为另一个算法。

 

参考资料:

    《重构-改善既有代码的设计》

  

posted @ 2020-07-20 21:24  diameter  阅读(139)  评论(0编辑  收藏  举报