臨時欄位
「臨時欄位」是類別內部只在特定演算法期間或在某些條件下設定和使用的變數。其餘時間,它坐在那裡是 null 或 0。
這令人困惑,因為物件應該代表一個完整的狀態。如果欄位 result 只在 calculate() 運行時有 效,為什麼它是類別的欄位?這讓檢查物件的開發者感到困惑,並想知道,「為什麼 result 是 null?它壞了嗎?」
氣味的跡象
- 一個欄位大部分時間是 null。
- 一個方法不接受參數,但依賴在不同方法中發生的欄位驗證。
- 你必須在呼叫
runAlgo()之前呼叫initAlgo()。
氣味的原因
過長參數列:開發者試圖避免向輔助方法傳遞很多參數,所以他們只是把它們儲存為實例欄位(對類別來說是全域的)。
重構配方
- 提取類別
- 用方法物件替換方法
提取類別
如果臨時欄位一起用於特定操作,將它們和那個操作移到新類別中。
之前:
class Order {
// 這些只在「計算」期間使用
private double tempTax;
private double tempDiscount;
public double calculateTotal() {
tempTax = 0.1;
tempDiscount = 0.5;
// ... 使用欄位的複雜邏輯
return result;
}
}
之後:
class Order {
public double calculateTotal() {
return new PriceCalculator(this).calculate();
}
}
class PriceCalculator {
private double tax;
private double discount;
private Order order;
public PriceCalculator(Order order) {
this.order = order;
}
public double calculate() {
// 現在 "tax" 和 "discount" 是*這個*物件的永久欄位
// 它們不再是 Order 的臨時欄位。
}
}
用方法物件替換方法
類似於提取類別,這個技術將方法變成它自己的物件,所以局部變數變成那個新物件的欄位。