l

2016年3月3日 星期四

用Replace Method With Method Object移除Long Method怪味道

Feb. 14 23:25~23:59

螢幕截圖 2016-02-14 23.59.31

 

有時候鄉民們會遇到一種情況,就是函數(method)很長且邏輯很複雜,你想用Extract Method重構整理這個大函數。但是這個函數因為過於複雜導致於你一下子不知道該如何整理,又或者是抽離出來的子函數擺在原本的類別裡面好像又沒有什麼關聯性。這時候你可以考慮套用Replace Method With Method Object重構,先把這個「燙手山芋」移到一個新的類別裡面,之後再慢慢處裡。

▼以下範例節錄自《Refactoring》。Account類別有一個gamma()函數,裡面有很多複雜的邏輯你一下子也看不太懂在作什麼,總之它最後回傳一個int。

螢幕截圖 2016-02-14 23.33.06

 

很顯然gamma()函數有著Long Method怪味道,你可以試著用Extract Method或是昨天提到的Replace Temp With Query來拆解它。但是gamma()函數看起來和Account的關係好像不大,如果就地拆解怕會無端增加Account類別的複雜度,怎麼辦?

***

▼這時候可以套用Replace Method With Method Object重構,把gamma()直接「升級」成為一個Method Object。做法就是新增一個Gamma類別,將原本gamma()函數的內容移到Gamma類別的compute()函數。

螢幕截圖 2016-02-14 23.40.15

 

▼然後原本Account類別的gamma()函數直接呼叫Gamma類別的compute()函數即可。現在gamma()函數從原本的Long Method變成Short Method了,清爽許多。

螢幕截圖 2016-02-14 23.43.23

 

這時候如果還想繼續整理Gamma類別的compute()函數,抽離出來的method就直接放在Gamma類別裡面,比較容易理解。

***

看到這裡鄉民們不知道是否發現Replace Method With Method Object其實是Extract Class的一種特例,只是抽離出來的Class沒有domain層次的意義,僅是用來代表一個實作層次的函數物件(Method Object)而已。

***

友藏內心獨白:這也是模組化的一種技巧。

1 則留言:

  1. 嗯,基本上這個技巧就只會存在像 Java 這樣的語言,常常為了一個簡單的function, 卻要先造一個object後再作一個compute(), do(), execute()之類的無意義動作。anyway, refactoring 跟 design patterns一樣,往往跟語言機制強相關,知道idea後就自行變化了~

    回覆刪除