(135)Replace_Method_With_Method_Object
將這個函式放近一個單獨物件中,如此一來區域變數就成了物件內的欄位。然後你可以在同一個物件中將這個大型函式分解為數個小型函式
classDiagram
Order ..> PriceCalculator
Order : Price()
PriceCalculator --> Order
PriceCalculator : int primaryBasePrice
PriceCalculator : int SecondaryBasePrice
PriceCalculator : int tertiaryBasePrice
PriceCalculator : compute()
動機
書中不斷向讀者強調小型函式的優美。只要將相對獨立的程式碼從大型函式中提煉出來,就可以大大提升程式碼可讀性。
但區域變數的存在會增加函式分解難度。除了用(120)Replace_Temp_With_Query可以減輕負擔,,但有時候你會發現根本無法拆解。這種情況只能使用目前這大絕招。
此方法會將所有的區域變數都變成一個函式物件的欄位,然後你就可以針對新物件使用(110)Extract_Method,創造新函式,從原本大型拆解變短。
作法
- 建立一個新的Class,根據【待被處理的函式】的用途命名
- 在新Class建立欄位,用以保存原先大型函式所駐物件。同時針對舊函式每個暫時變數和每個參數都建立變數
- 在新Class寫一個建構式,接收原物件及原函式的所有參數
- 在新class建立新函式Compute()
- 將原函式的程式碼copy到compute()中
範例
書中範例未必很完美,因為用這到這個方法的狀況通常都超級複雜,所以只能示意,但範例已經點出具體作法,不妨礙理解
範例1
class Account
int gamma (int inputVal, int quantity, int yearToDate){
int importantValue1 = (inputVal * quantity) + delta();
int importantValue2 = (inputVal * yearToDate) + 100;
if ((yearToDate - importantValue1) > 100){
importantValue2 _= 20;
int importantValue3 = importantValue2 * 7;
return importantValue3 -2 * importanValue1;
}
}
轉換第一步
Class Gamma {
private ReadOnly Account _account;
private int inputVal;
private int quantity;
private int yearToDate;
private int importantValue1;
private int importantValue2;
private int importantValue3;
}
步驟二:建立建構式
Gamma (Account source, int inputValArg, int quantityArg, int yearToDateArg){
_account = source,
inputVal = inputValArg;
quantity = quantitiyArg;
yearToDate = yearToDateArg;
}
步驟三:把原本還是搬到compute()
int compute(){
int importantValue1 = (inputVal * quantity) + delta();
int importantValue2 = (inputVal * yearToDate) + 100;
if ((yearToDate - importantValue1) > 100){
importantValue2 _= 20;
int importantValue3 = importantValue2 * 7;
return importantValue3 -2 * importanValue1;
}
}
步驟四:在原本的位置改成呼叫新的函式
int gamma(int inputVal,int quantity,int yearToDate){
return new Gamma(this, inputVal, quantity, yearToDate).compute();
}
後繼
這就是這個方法最重要的原則。它帶來的好處是:現在我可以輕鬆地對compute()函式採取(110)Extract_Method,不必擔心引數傳遞。
再根據使用(135)Replace_Method_With_Method_Object方法後,重構一次(110)Extract_Method
int compute(){
int importantValue1 = (inputVal * quantity) + delta();
int importantValue2 = (inputVal * yearToDate) + 100;
importantThing();
int importantValue3 = importantValue2 * 7;
return importantValue3 -2 * importanValue1;
}
void importantThing(){
if ((yearToDate - importantValue1) > 100){
importantValue2 _= 20;
}
}