文章出處
文章列表
重構
以查詢取代臨時變量
臨時變量的問題在于:它們是暫時的,而且只能在所屬函數內使用。由于臨時變量只能在所屬函數內可見,所以它們會趨勢你寫出更長的函數,因為只有這樣你猜可以訪問到所需要的臨時變量,如果把臨時變量替換為一個查詢,那么同一個類中的所有函數都可以獲得這份信息。
范例
double getPrice() {
int basePrice = number * itemPrice;
double discountFactor;
if (basePrice > 1000) discountFactor = 0.95;
else discountFactor = 0.98;
return basePrice * discountFactor;
}
將臨時變量聲明為final
double getPrice() {
final int basePrice = number * itemPrice;
final double discountFactor;
if (basePrice > 1000) discountFactor = 0.95;
else discountFactor = 0.98;
return basePrice * discountFactor;
}
把賦值動作的右側表達式提煉出來
double getPrice() {
final int basePrice = getBasePrice();
final double discountFactor = getDiscount();
return getBasePrice() * discountFactor;
}
int getBasePrice() {
return number * itemPrice;
}
double getDiscount() {
if (getBasePrice() > 1000) return 0.95;
else return 0.98;
}
最后
double getPrice() {
final int basePrice = getBasePrice();
return getBasePrice() * getDiscount();
}
int getBasePrice() {
return number * itemPrice;
}
double getDiscount() {
if (getBasePrice() > 1000) return 0.95;
else return 0.98;
}
引入解釋性變量
你有一個復雜的表達式,將該復雜的表達式(或其中一部分)的結果放進一個臨時變量,以此變量名稱來解釋表達式的用途。
if ((platform.toUpperCase().indexOf("MAC") > -1) &&
(browser.toUpperCase().indexOf("IE") > -1) &&
wasInitialized() && resize > 0)
{
// do something
}
可以重構為:
final boolean isMacOS = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = platform.toUpperCase().indexOf("IE") > -1
final boolean wasResized = resize > 0;
if (isMacOS && isIEBrowser && wasInitialized() && wasResized)
{
// do something
}
分解臨時變量
如果你的程序有某個臨時變量賦值超過一次,它既不是循環變量也不是結果收集變量,這就意味著這個臨時變量在函數中承擔了一個以上的責任,如果臨時變量承擔多個責任,就應該針對每次賦值,創造一個獨立,對應的臨時變量。
double temp = 2 * (height + width);
System.out.println(temp);
temp = height * width;
System.out.println(temp);
應該改寫成:
final double perimeter = 2 * (height + width);
System.out.println(perimeter);
final double area = height * width;
System.out.println(area);
以函數對象取代函數
將這個函數放進一個單獨的對象中,如此一來局部變量就成了對象內的字段,然后你可以在同一個對象中將這個大型函數分解為多個小型函數
class Account {
int gamma(int inputVal, int quantity, int yearToDate) {
int importantValue1 = (inputVal * quantity) + delta();
int importantValue2 = (inputVal * yearToDate) + 100;
if ....
....
....
return importantValue3 - 2 * importantValue1;
}
}
第一步:把這個函數變為一個函數對象,并加入一個構造函數
class Gamma {
private final Account account;
private int inputVal;
private int quantity;
private int yearToDate;
private int importantValue1;
private int importantValue2;
pirvate int importantValue3;
Gamma(Account account, int inputVal, int quantity, int yearToDate) {
this.xx = xx
...
...
...
}
}
現在可以把原本的函數搬到compute()中了,
int compute() {
int importantValue1 = (inputVal * quantity) + account.delta();
int importantValue2 = (inputVal * yearToDate) + 100;
if ....
....
....
return importantValue3 - 2 * importantValue1;
}
然后,我們修改舊的函數:
int gamma(int inputVal, int quantity, int yearToDate) {
return new Gamma(this, inputVal, quantity, yearToDate).compute();
}
文章列表
全站熱搜