l

2016年4月8日 星期五

用Replace Type Code with State/Strategy移除Primitive Obsession怪味道

March 28 16:00~16:43

螢幕截圖 2016-03-28 16.42.50

 

Replace Type Code with State/Strategy重構和昨天介紹的Replace Type Code with Subclasses很像,主要的差別在於,前者可以在執行期間(runtime)更換type code所代表的型別,而後者不行。舉上次的例子,HardDrive物件在產生之後,只能是SATA、SAS、SCSI、USB其中一種,不可能剛開始是SATA硬碟,執行到一半變成SCSI硬碟。在這種情況,可以採用Replace Type Code with Subclasses重構移除switch case裡面的type code。

▼今天的例子和昨天一樣,但是假設HardDrive在執行期間可以更換型別XD。

螢幕截圖 2016-03-28 16.10.56

***

▼為了用Strategy取代type code,先新增一個HardDriveType抽象類別,裡面的程式碼和昨天重構後的HardDrive類別很像,有一個factory method—newType()用來產生不同型別的硬碟。和昨天的例子不同之處在於,昨天由HardDrive的子類別來代表不同型別的硬碟,今天的例子由HardDriveType來代表,如此便可在執行期間藉由更改HardDriveType所只到的具體子類別達到讓HardDrive物件動態改變硬碟型別的目的。

螢幕截圖 2016-03-28 16.13.54

 

▼接下來就要讓不同的硬碟型別繼承HardDriveType類別,以SATA類別為例,只要覆寫getTypeCode()函數即可。

螢幕截圖 2016-03-28 16.19.33

 

▼套用Replace Type Code with State/Strategy重構後的HardDrive類別的_type資料成員型別由int改成HardDriveType。 看到這裡鄉民們可能覺得很奇怪,怎麼smartCheck()的switch case還在?smartCheck()的行為不是應該移到個相對應HardDriveType子類別裡面嗎?例如doSATASmartCheck()要移到SATA類別裡面。如果改成套用Startegy設計模式的確是會變成這樣,但這個重構只做到Replace Type Code with State/Strategy,也就是把type code用state或strategy取代,行為的部分如果需要搬移可以套用Replace Conditional with Polymorphism繼續重構下去。

螢幕截圖 2016-03-28 16.28.41

***

友藏內心獨白:一定要分兩次,不能一次套完嗎?

沒有留言:

張貼留言