Tuesday, December 4, 2012

重構-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)










No comments:

Post a Comment