第一章 重構,第一個案例

1.1 起點

背景:影片出租商店應用。涉及三個類:電影,出租,顧客。

源碼鏈接:

https://github.com/sigma65535/Refactoring_improving_the_design_of_existing_code/tree/master/Chapter1

UML圖:


問題所在:

在Customer中statement()這個函數非常長,大約有50行。而且做了不止一件事情。(swich語句完成折扣計算,result完成結果返回輸出)。《clean code》中對函數的要求是:短小,一個函數只做一件事等。

Tip:程序需要添加特性時,原有的代碼結構無法方便的擴展,此時需要重構。

1.2 重構的第一步

必須建立良好的測試環境,好的測試是重構的根本。

1.3 分解重構statement()
1.2 重構的第一步

必須建立良好的測試環境,好的測試是重構的根本。

1.3 分解重構statement()

函數中最複雜的是switch這個邏輯泥團,如下圖所示:


Eclipse IDE中有強大的重構工具,方便我們進行重構。如下:


處理步驟1:將switch這個函數提取爲一個單獨的函數;

方法:



在statement()函數下,新方法已經抽離出來。


函數的參數變量thisAmount其實是個常數,可以拿到函數裏邊來進行處理。(《clean code》 函數的參數越少越好)。


進一步,將thisAmount變量重名爲改爲result更合理。依然是refactor菜單Rename,

這樣方法內的thisAmount會一同變爲result,這樣可以避免手動修改出錯。

2.搬移金額計算代碼

getCharge()函數並沒有涉及Customer類中的變量,因此放這不合適。在該方法中Rental類有關,因此應將getCharge()搬移到Rental.

選中方法後,執行Move……操作,IDE自動會分析方法應該移動到Rental類下邊。



金額搬遷之後的,所有類的狀態:


3.臨時變量往往容易導致大量參數傳來傳去,觀察下邊的代碼,thisAmount應該刪除。


4. 同樣的方法來處理frequentRenterPoints的計算代碼,將其提煉爲一個單獨的方法getFrequentRenterPoints(),並移動到Rental類中。


分析上圖的矩形區域內的代碼,每次進入while循環的if語句時 frequentRenterPoints+2,否則frequentRenterPoints+1;根據此寫出代碼,並移動到Rental類之後。



frequentRenterPoints()處理之後的UML圖如下:


5. 去除臨時變量totalAmount,將其值得計算用函數getTotalAmount()替代。


6 同樣處理frequentRenterPoints,用方法getFrequentRenterPoints()替代

private int getFrequentRenterPoints(){
		int result = 0;
		Enumeration<Rental> rentals = _rentals.elements();
		while (rentals.hasMoreElements()) {
			Rental each = (Rental) rentals.nextElement();
			result += each.getFrequentRenterPoints();
		}
		return result;
	}


1.4 利用多態邏輯取代與價格相關的條件邏輯。

引入了state模式來進行重構。

1.5重構總結

各個重構過程中UML的變換圖如下:









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章