重構筆記——以查詢取代臨時變數
阿新 • • 發佈:2019-02-16
在上一篇文章中介紹了“ 內聯臨時變數“。本文將介紹“以查詢取代臨時變數”這種重構手法。
下面讓我們來學習這種重構手法吧。
開門見山
發現:你的程式以一個臨時變數儲存某一表達式的運算結果。
解決:將這個表示式提煉到一個獨立函式中。將這個臨時變數的所有引用點替換為對新函式的呼叫。
//重構前
double basePrice = _quantity * _itemPrice;
if(basePrice > 5000)
return basePrice * 0.95;
else
return basePrice * 0.98;
//重構後 if(basePrice() > 5000) return basePrice() * 0.95; else return basePrice() * 0.98; ... double basePrice(){ return _quantity * _itemPrice; }
動機
我們都知道臨時變數都是暫時的,而且只能在所屬的函式中使用。所以它們會驅使你寫出更長的函式,因為只有這樣你才能訪問到需要的臨時變數。如果把臨時變數替換為一個查詢,那麼同一個類中所有函式都將可以獲得這份資訊。這將帶給你極大幫助,使你能夠為這個類編寫出更清晰的程式碼。
該重構方法往往是你運用提煉函式之前必不可少的一個步驟。區域性變數會使得程式碼難以提煉,所以應該儘可能把它們替換為查詢式。比較簡單的情況是:臨時變數只被賦值一次,或者賦值給臨時變數的表示式不受其它條件影響。
做法
對於簡單的情況: (1)找出只被賦值依次的臨時變數(如果被使用多次,考慮將其分割成多個變數,對應在後續重構方法中)。我們常常使用臨時變數儲存迴圈中的累加資訊。在這種情況下,整個迴圈都可以被提煉為一個獨立的函式,這可以減少原函式中幾行迴圈邏輯程式碼。該手法的使用可能會讓你擔心效能上的問題。就像和其它效能問題一樣,我們現在不用管它,因為十有八九根本沒有造成任何影響。就算真的出問題了,你也可以在優化時期解決它。程式碼組織良好,你也會發現更有效的優化方案;如果沒有進行重構,好的優化方案就可能與你失之交臂。
示例
我們從一個簡單函式開始://重構前
double getPrice() {
int basePrice = _quantity * _itemPrice;
double discountFactor;
if (basePrice > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice * discountFactor;
}
我們希望將其中的兩個臨時變數都去掉。當然,每次一個進行處理。程式碼雖然簡單,但是還是有必要先把臨時變數宣告為final,檢查它們是否的確只被賦值一次。
double getPrice() {
final int basePrice = _quantity * _itemPrice;
final double discountFactor;
if (basePrice > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice * discountFactor;
}
這樣,一旦有問題編譯器就會警告。之所以需要這個做是因為如果臨時不安路口不只被賦值一次,就不該進行這項重構。
下面開始替換臨時變數,每次一個,不要著急,按部就班。
首先,把賦值動作右側表示式提煉出來:
double getPrice() {
final int basePrice = basePrice();
final double discountFactor;
if (basePrice > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice * discountFactor;
}
private double basePrice() {
return _quantity * _itemPrice;
}
然後,編譯並測試,再開始使用內聯臨時變數。
首先把臨時變數basePrice的第一個引用點替換掉:double getPrice() {
final int basePrice = basePrice();
final double discountFactor;
if (basePrice() > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice * discountFactor;
}
編譯、測試,然後進行下一個。由於下一個是最後一個引用點,所以把basePrice臨時變數的宣告式一併去掉:double getPrice() {
final double discountFactor;
if (basePrice() > 5000)
discountFactor = 0.95;
else
discountFactor = 0.98;
return basePrice() * discountFactor;
}
完成basePrice之後,以類似的方法提煉出discountFactor():
double getPrice() {
final double discountFactor = discountFactor() ;
return basePrice() * discountFactor;
}
private double discountFactor(){
if (basePrice() > 5000)
return 0.95;
else
return 0.98;
}
你會發現,如果沒有把臨時變數basePrice替換為一個查詢式,將多麼難以提煉discountFactor()!
最終,getPrice()變成這樣:
//重構後
double getPrice() {
return basePrice() * discountFactor();
}
本文主要介紹了重構手法——以查詢取代臨時變數。通過重構後代碼可見,程式碼變的相當地簡潔了,程式碼所表達的意圖也變的很清晰了。一旦程式碼中出現問題,修改起來也比較輕鬆,因為程式碼很簡短、清晰。我想你是否也慢慢喜歡上重構了呢!如果是,那麼就一起學習、進步,讓程式碼變得漂亮吧! 最後,希望本文對你有所幫助。有問題可以留言,謝謝。(PS:下一篇將介紹重構筆記——引入解釋性變數)