l

2016年2月17日 星期三

用Pull Up Method與FormTemplate Method移除Duplicated Code怪味道

Feb. 05 22:40~23:58

螢幕截圖 2016-02-06 00.21.18

 

▼你正在開發一個授信系統,你幫這個系統定義了一個FinancialChecker抽像類別做為不同授信對象財務狀況檢查邏輯實做的介面。

螢幕截圖 2016-02-05 23.13.19

 

▼你實做了LenderChecker與SupplierChecker兩個類別,分別用來檢查一般貸款者與供應商的財務狀況。

螢幕截圖 2016-02-05 23.43.09

螢幕截圖 2016-02-05 23.44.27

一般借款者需要檢查他的銀行、信用、借款、收入與股票,而供應商只需要檢查銀行、信用與借款。兩種檢查邏輯有點像但又不是完全一樣。

***

觀察上面程式我們發現:

  • 財務狀況檢查最複雜就是一般借款者的情況,需要檢查五種條件,而供應商的檢查條件是一般借款者的子集合。
  • 既使檢查項目相同,例如checkBank()、checkCredit()、checkLoan(),但LenderChecker與SupplierChecker類別關於這三個函數的實做可能有些相同、有些不同;也就是子類別有各自的行為。

我們先套用Pull Up Method把checkBank()、checkCredit()、checkLoan()這三個共同使用到的函數往上拉到FinancialChecker類別。假設checkCredit()與checkLoan()有預設的實做,checkBank()沒有,所以把checkBank()宣告成abstract要求子類別一定要提供實做。

螢幕截圖 2016-02-05 23.36.01

 

▼把共同的函數往上拉之後LenderChecker與SupplierChecker類別程式碼稍微乾淨一些。

螢幕截圖 2016-02-05 23.39.50

螢幕截圖 2016-02-05 23.41.45

***

接下來可以套用FormTemplate Method,更進一步把check()往上拉到FinancialChecker身上,把check()當成一個檢查財務狀況的模板(template method),子類別再依據各自的需要去覆寫hook mehtod或是primitive operation(就是template method所呼叫的函數)。

▼改完之後FinancialChecker變成這樣:

螢幕截圖 2016-02-05 23.50.37

 

▼LenderChecker與SupplierChecker變得清爽多了。

螢幕截圖 2016-02-05 23.52.53

螢幕截圖 2016-02-05 23.52.58

***

看到這裡應該可以發現《Refactoring》書中幾十個重構方法的顆粒度大小不一。小到改個名子,大到重構成design pattern,或是Separate Domain from Presentation這種已經有點軟體架構味道的重構。全部一視同仁都放在一起也不知道是好是壞,留給鄉民們自行判斷。

***

友藏內心獨白:這是一種「伸縮自如的橡膠拳」概念嗎?

沒有留言:

張貼留言