l

2016年3月9日 星期三

用Introduce Parameter Object移除Long Parameter List怪味道

March 09 09:40~10:25

螢幕截圖 2016-03-09 10.24.56

 

Long Parameter List怪味道的說明請參考〈談談壞味道(3):Long Parameter List & Divergent Change〉,今天介紹Introduce Parameter Object重構來移除這個怪味道。

▼Monitor類別管理與監控若干個Device類別,Monitor的getDevicesReadingBetween()函數傳回所有讀數介於high與low之間的Device。Introduce Parameter Object重構將若干個參數用參數物件取代,在這個例子中雖然getDevicesReadingBetween()只有兩個參數,請先把這兩個參數想像成Long Parameter List的成員之一,這樣子才不會覺得例子怪怪的XD。

螢幕截圖 2016-03-09 09.56.29

 

▲請看getDevicesReadingBetween()函數實作內容,有一個if條件式判斷:

if ( (device.getReading() <= high) &&
    (device.getReading() >= low)){

如果把參數high, low放到參數物件中,並且把比對的邏輯也一併移入,或許可以減化這裡的if條件式。

***

▼套用Introduce Parameter Object,新增Range類別,將high, low變成它的資料成員,然後套用Extract Method加上Move Method,把剛剛看到Monitor類別的getDevicesReadingBetween()函數中的if判斷邏輯搬家到Range函數中,取名為isInclude()。

螢幕截圖 2016-03-09 10.04.30

 

▼有了Range類別之後,Monitor類別的getDevicesReadingBetween()函數就變得清爽許多。

螢幕截圖 2016-03-09 10.11.11

***

從這個例子可以發現,Long Parameter List在許多情況下是一種使用基本型別的偏好(Primitive Obsession,請參考〈談談壞味道(5):Data Clumps & Primitive Obsession〉)。因為傳入的參數是基本型別,沒有行為,所以函數本身就需要比較多的邏輯來操作這些參數。套用Introduce Parameter Object之後,最簡單的好處是把參數打包,減少傳入的「數量」,更進一步則可考慮將屬於操作這些參數的行為搬移到它的身上。如此一來除了可以減少客戶端的邏輯,當客戶端有很多不同的物件時,也可減少Duplicated Code。

***

友藏內心獨白:歡迎使用小物件。

1 則留言: