《重构:改善既有代码的设计》读书笔记1——重新组织函数

https://www.jianshu.com/p/d91987818ee6

(1):Extract Method 提炼函数:

当看到一个过长函数或需要注释才能让人理解用途的代码,需要将这段代码放进一个独立函数中。

  1. 如果每个函数粒度都很小,那么函数被复用的机会就更大
  2. 每个小函数起一个好名字,读这些函数就像读注释。
  3. 覆写起来更容易。

注意点:如果你想不到一个有意义的名字,先别动。

例子:

1 void printOwing(double amount){
2     printBanner();
    //print details
3 System.out.println("name"+_name); 4 System.out.println("amount"+_amount); 5 }

==>

void printOwing(double amount){
    printBanner();
    printDetails(amount);
}
void printDetails(double amount){
    System.out.println("name"+_name);
    System.out.println("amount"+_amount);
}

Extract method通常会遇到三种情况:无局部变量、有局部变量(只读,修改)。

  1. 无局部变量情况下,只需抽取即可。
  2. 有局部变量,但被提炼的代码段只是读取这些变量的值并不修改它们,可以简单的将它们作为参数传给目标函数即可。
  3. 如果被提炼的代码段对局部变量赋值。此时情况变得更复杂了。
    • 这个变量只在被提炼的代码段中使用,可以将这个变量移到被提炼的代码段中。
    • 在被提炼的代码段之外也使用了。只需要让目标函数增加返回值即可。

  (2):Inlined Method(内联函数)

有时候会遇到函数,其内部代码和函数名称同样清晰易读。也可能你重构了该函数,使得其内容和名称同样清晰。果真如此,你就应该去掉这个函数,直接使用其中代码,间接性可能带来帮助,但非必要的间接性让人总是不舒服。

其次,你手上有一群组织不甚合理的函数,可以将它们都内联到一个大型函数中,在从中提炼出组织合理的小型函数,

例:

 1 int getRating(){
 2     return(moreThanFiveLateDeliveries()) ? 2:1;
 3 }
 4 boolean moreThanFiveLateDelivers(){
 5     return _numberOfLateDeliveries>5;
 6 }
 7 
 8 -- 9 
10 int getRating(){
11     return (_numberOfLateDeliveries>5)?2:1;
12 }

     (3) 内联临时变量 Lnline Temp    临时变量只被表达式赋值一次,将所有对该变量的引用动作,替换为对它赋值的那个表达式自身。

  (4)Replace Temp with Query(以查询取代临时变量)

    你的程序以一个临时变量保存某一表达式的运算结果。将这个表达式提炼到一个独立的函数中。将这个临时变量的所有引用点替换为对新函数的调用

例,略。

    好处:临时变量只能在所属函数内使用。由于临时变量只在所属函数内可见,所以它们会驱使你写出更长的函数。如果把临时变量替换成一个查询,那么同一类中所有的函数都将可以获得这份信息。

  (5)Introduce Explaining Variable(引入解释性变量)

    将复杂的表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式的用途。------更多的extract method()处理。当extract method需要花费大量工作量时 才使用该方法。

  例:

 1 if((platform.toUpperCase().indexof("MAC")>-1)&&(browser.toUpperCase().indexof("IE)>-1)&&
 2 wasInitialized()&&resize>0){
 3 //do something
 4 }
 5 -- 6 final boolean isMac=platform.toUpperCase().indexof("MAC")>-1;
 7 final boolean isIE=browser.toUpperCase().indexof("IE)>-1;
 8 final boolean wasResized=resize>0;
 9 if(isMac&&isIE&&wasInitialized()&&wasResized){
10 //
11 }

  (6)Split Temporary Variable(分解临时变量)

针对每次赋值,创造一个独立、对应的临时变量。如果临时变量被赋值超过一次,就意味着在函数中承担多个责任,它就应该被替换分解为多个临时变量,每个变量只承担一个责任。

double temp=2*(_height+_width)
System.out.println(temp);
temp=_height*_width;
System.out.println(temp);

--final double perimeter = 2*(_height+_width);

final double area=_height*_width;

  (7)Remove Assignments to Parameters(移除对参数的赋值)

代码对一个参数进行赋值,以一个临时变量取代该参数的位置。在java代码中,不要对参数赋值。!!!

可以在参数列表中添加final !。 但即使参数为final 仍可修改它所指向的对象。

  (8)replace method with method object 以函数对象取代函数。

有一个大型函数,其局部变量的使用是你无法采用extract method. 将这个函数放进一个单对对象中,如此一来局部变量就变成对象内的字段,后你可以在同一个对象中将这个大型函数分解成为多个小函数。

  (9)替换算法。 

将函数本体替换成另一种算法。请尽可能的分解原先的函数,替换一个巨大而复杂的算法是非常困难的。

猜你喜欢

转载自www.cnblogs.com/zdcsmart/p/12486891.html