當你的程序以一個臨時變量保存某一表達式的運算結果
將這個表達式提煉到一個獨立函數中,將這個臨時變量的所有[被引用點]替換爲[對新函數的調用],新函數可被其他函數使用
java 代碼
-
double basePrice=_quantity * _itemPrice;
-
if(basePrice>1000){
-
return basePrice * 0.95;
-
else
-
return basePrice * 0.38;
-
}
-
......
提煉後:
java 代碼
-
if (basePrice()>1000){
return basePrice() * 0.95 -
else
-
return basePrice() * 0.38
-
}
-
......
-
double basePrice(){
-
return _quantity * _itemPrice;
}
動機:
臨時變量的問題在於:它們是暫時的,而且只能在所屬函數內使用,由於臨時變量只有在所屬內纔可見,所以它們會驅使你寫出更長的函數,因爲只有這樣你才能訪問到想要訪問的臨時變量,如果把臨時變量替換爲一個查詢式(query method),那麼同一個CLASS中的所有函數都將獲得這份信息。這將帶給你極大幫助,使你能夠爲這個CLASS編寫更清晰的代碼。
這個重構手法較爲直率的情況就是:臨時變量只被賦值一次,或者賦值給臨時變量的表達式不受其他條件影響,其他情況比較情況棘手,但也有可能發生,你可能需要先運用Split Temporary Variable 或Separate Query from Modifier 使情況變得簡單一些。如果你想替換的臨時變量是用來收集結果的(例如循環中的累加值),你就需要將某些程序的邏輯(例如循環)拷貝到查詢式(query method)去。
作法:
- 找出只被賦值一次的臨時變量
- 將臨時變量聲明爲 final
- 編譯(這可確保臨時變量的確只被賦值一次)
- 將對該臨時變量賦值之語句的等號右側部分提煉到一個獨立函數中。詳細步驟:首先將函數聲明爲private,之後你可能會發現有更多CLASS需要使用它,彼時你可輕易放鬆對它的保護。確保提煉出來的函數無任何連帶影響,就對它進行Separate Query from Modifier
- 編譯,測試
範例:
首先,我從一個簡單函數開始:
java 代碼
-
double getPrice()
-
{
-
int basePrice=_quantity+_itemPrice;
-
double discountFactor;
-
if(basePrice>1000)
-
discountFactor=0.95;
-
else
-
discountFactor=0.98;
-
return basePrice = discountFactor;
-
-
}
我希望將這個兩個變量都替換掉,當然,每次一個。
儘管這裏的代碼十分清楚,我還是先把臨時變量聲明爲final,檢查它們是否的確只被賦值一次:
java 代碼
-
double getPrice()
-
{
-
final int basePrice = _quantity * _itemPrice;
-
final double discountFactor;
-
if(basePrice>1000)
-
discountFactor=0.95;
-
else
-
discountFactory=0.98;
-
return basePrice * discountFactor;
-
}
這麼一來,如果有任何問題,編譯器就會警告我,之所以先做這件事,因爲如果臨時變量不只被賦值一次,不該進行這項重構了,接下來我開始替換臨時變量了,每次一個,首先我把賦值動作的右側表達式提煉出來。
java 代碼
-
double getPrice()
-
{
-
final int basePrice = basePrice();
-
final double discountFactor;
-
if(basePrice >1000)
-
discountFactor =0.95;
-
else
-
discountFactor =0.98;
-
return basePrice * discountFactor;
-
}
-
private int basePrice()
-
{
-
return _quantity * _itemPrice;
-
}
-
再把臨時變量的引用點替換掉:
java 代碼
-
double getPrice()
-
{
-
final int basePrice = basePrice();
-
final double discountFactor;
-
if ( basePrice()>1000 )
-
discountFactor = 0.95;
-
else
-
discountFactor = 0.98;
-
return basePrice() * discountFactor;
-
}
下一步:
java 代碼
-
double getPrice()
-
{
-
final double discountFactor;
-
if ( basePrice()>1000 )
-
discountFactor = 0.95;
-
else
-
discountFactor = 0.98;
-
return basePrice() * discountFactor;
-
}
下一步(仔細觀察代碼)
java 代碼
-
double getPrice()
-
{
-
return basePrice() * discountFactor();
-
}
-
-
private double discountFactor()
-
{
-
if ( basePrice()>1000 )
-
return 0.95;
-
else
-
return 0.98;
-
}
-
-
private int basePrice()
-
{
-
return _quantity * _itemPrice;
-
}
是多麼簡單啊(代碼有錯請指點)