重構-Code Refactoring-Vol1

摘要:重構-Code Refactoring-Vol1

 

1.ExtractMethod

2.Inline Method

3.Inline Temp

 


 

 

1.ExtractMethod

 

Motivation:

當一個Method過長(long Method)或是需要注釋才能讓能理解的程式碼用途,通常會把它放入一個獨立函式中。

長度不一定指的是行數,"語意"當如果提煉出來能夠強化程式碼語意,那就提煉吧。

Example:

No Local Variables:

void printOwing()

{

    //print Banner

 

    System.out.println("**************************************");

    System.out.println("*************Customer Owes***********");

    System.out.println("**************************************");

    //print Detail

 

    System.out.println("name:" _name);

    System.out.println("amount:" _amount);

 

 

}

Result:

void printOwing()

{

    printBanner();

 

 

    //print Detail

 

    System.out.println("name:" _name);

    System.out.println("amount:" _amount);

 

 

}

void printBanner()

{

 

    //print Banner

 

    System.out.println("**************************************");

    System.out.println("*************Customer Owes***********");

    System.out.println("**************************************");

 

}

 

Using Local Variables:

 

void printOwing()

{

    printBanner();

   //calculate outStanding

   double outStanding = 0.0f;

    while(xxx)

   {

    Order order =(Order)e.nextElement();

    outstanding += each.getAmount();

   }

 

 

    //print Detail

 

    System.out.println("name:" _name);

    System.out.println("amount:"outstanding);

 

 

}

Result:

 

 

 

 

void printOwing()

{

    printBanner();

   //calculate outStanding

   double outStanding = 0.0f;

    while(xxx)

   {

    Order order =(Order)e.nextElement();

    outStanding += each.getAmount();

   }

 

 

    printDetail(outStanding);

 

 

}

 

void printDetail(double outStanding)

{

 

    System.out.println("name:" _name);

    System.out.println("amount:"+outstanding); 

 

}

 

Reassigning

 

 

如果被提煉碼對區域變數賦值,問題可能會變複雜,分為暫時變數的問題。但如果發現源函式的參數被賦值,則要使用Remove Assignments to Parameters

被賦值的暫時變數的問題也分兩種:

1.這個變數只在被提煉程式碼區段中使用:將這個暫時變數的宣告式移動被提煉的程式碼中,然後再一起被提煉出去。

2.被提煉碼之外的程式碼也使用這個變數,這情況再分兩種:1.如果這個變數在被提煉碼之後未被在使用,只需直接在目標函式中修改它就可以了;如果這個變數在被提煉碼之後繼續使用這個變數,就需要讓目標函式返回。

 

 

2.Inline Method

 

 

Motivation:

 

有時候遇到某些函式,其內部程式碼和函式名稱同樣清晰易讀,應該可以去掉這個函式,直接使用其中的程式碼

Example:

int getRating()

{

    return (moreThanFiveLateDeliveries())?2:1;

}

bool moreThanFiveLateDeliveries()

{

    return _numberOfLateDeliveries > 5;

}

Result:

int getRating()

{

    return (_moreThanFiveLateDeliveries >5)?2:1;

}

 

3.Inline Temp

Motivation:

Inline Temp多半作為 Replace Temp with Query的一部分作為使用,所以真正動機在後者。單獨使用Inline Temp的情況:發現某個暫時變數被賦予某個函式呼叫的回返值。

 

Example:

double basePrice = anOrder.basedPrice();

return (basePrice > 1000)

Result:

return (anOrder.basePrice() > 1000)