论坛首页 入门技术论坛

重构之提炼代码

浏览 2064 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-09-26  

前几天北京图书大厦买了两本书<<重构,改善既有代码的设计>>与<<agile with="" web="" development="" rails=""></agile>><agile with="" web="" development="" rails=""></agile>

特意把书的代码一个字一个字粘出来,望能帮助我们这些开发人员对"重构"理解提供一些帮助,

当你有一段代码可以被组织在一起独立出来

将这段代码放进一个独立函数中,并让函数名称解释该函数的用途

函数的命名是非常重要的,以前我做开发的时候,从来我就不考虑这么多,只要这个函数能跑起来就行,我也不去管那么多,现在看了"重构",感觉它有另外一种思想,望大家好好学习!!

java 代码
  1. void  printOwing(double amonut){   
  2. printBanner();   
  3. //print details
  4. System.out.println("name:"+_name);
  5. System.out.println(""amount:"+amount);
  6.   
  7. }  

 

重构后的代码:

java 代码
  1. void printOwing(double amonut){   
  2.      printBanner();
  3.      printDetails(amount
  4. }  
  5. void printDetails(double amount){
         System.out.println("name:"+_name);
  6.      System.out.println("amount:"+amount);
  7. }

可以看出现在变成了两个方法,把一部分语句抽出来做为一个方法!!

Extract Method 是最常见的重构方法之一。看见一个过长的函数或者一段需要注释才能让人理解用途的代码,就会将这个段代码放进一个独立函数中。

有数个原因造成简短面有良好的命名的函数。首先,如果每个函数的粒度都江堰市很小(finely grained),那么函数之间彼此复用的机会就更大了,其次,这会使高层函数代码读起来就像一系列注释;再者,如果函数都是细粒度,那么函数的覆写(override)也会更容易些.

作法:

  • 创造一个新函数,根据这个函数的意图来给它命名
  • 仔细检查提炼出的代码,看看其中是否引用了(作用域限于源函数)的变量(包括局部变量和源函数参数)
  • 检查是否有(仅仅用于被提炼代码)的临时变量,如果有,在目标函数中将它们声明为临时变量
  • 检查被提炼码,看看是否有任何局部变量的值被它改变,如果一个临时变量值被修改了,看看是否可以将被提炼码处理为一个查询(Query),并将结果值给相关变量,
  • 将被提炼代码中需要读取的局部变量,当作函数传给目标函数

范例1):无局部变量(No  Local Variables)

java 代码
  1. void printOwing()
  2. {     
  3.      Enumeration e =_orders.elements();
  4.      double outstanding=0.0;   
  5.  
  6.      //calculate outstanding 
  7.      System.out.println("*******************************"); 
  8.      System.out.println("********* Customer Owes********"); 
  9.      System.out.pritnln("*******************************");
  10.      
  11.      //calculate outstanding
  12.      while(e.hasMoreElements()
  13.      {
  14.           Order each=(Order)e.nextElement();
  15.           outstanding +=each.getAmount();
  16.    }
  17.  
  18.      //print details
  19.      System.out.println("name:"+_name);
  20.      System.out.println("amount:"+outstanding);
         
  21. }  

 重构后:

java 代码
  1. void printOwing(){   
  2.      Enumeration e=_orders.elements();  
  3.      double outstanding=0.0;
  4.      printBanner();
  5.      //calculate outstanding
  6.      while (e.hasMoreElements())
  7.      {
  8.            Order order=(Order)e.nextElement();
  9.            outstanding +=each.getAmount();
          } 
  10.  
  11.       //print details
  12.       System.out.println("name:"+_name);
  13.       System.out.println("amount:"+outstanding);
     
  14. }
  15.  
  16. void printBanner(){
  17.      //print banner
  18.      System.out.println("*******************************";
  19.      System.out.println("*********** Customer Owes *****");
  20.      System.out.println("*******************************"):
    }

 

范例2):对局部变量再赋值(Reassigning)

java 代码
  1. void printOwing(){   
  2.      printBanner();
  3.      double outstanding=getOutstanding();
  4.      printDetails(outstanding);
  5. }  
  6.  
  7. double getOutstanding()
  8. {
  9.    Enumeration e=_orders.elements();
  10.    while (e.hasMoreElements())
  11.    {
  12.       Order each=(Order)e.nextElement();
  13.       outstanding +=each.getAmount();
  14.     }
  15.    return outstanding;
    }

Enumeration 变量 e 只有被提炼码中用到,所以可以将它整个搬到新函数中,double 变量oustanding 在被提炼码内外都被用到,所以我必须让提炼的新函数返回它。

java 代码
  1. double getOutstanding()
  2. {   
  3.     Enumeration e=_orders.elements();
  4.     double result=0.0;
  5.     while(e.hasMoreElements())
  6.     {
  7.         Order each=(Order)e.nextElement();
  8.         result +=each.getAmount();
  9.      }
  10.     return result;
    }
  11.   

最后提炼成:

java 代码
  1. void print()   
  2. {   
  3.      printBanner();
  4.      double outstanding=getOutstanding();
  5.      printDetails(outstanding);
  6. }  
简单吧,呵呵
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics