每當我遇到一個工廠基於某些「低級」類型參數(如協議或外部資源的格式)將抽象基類實現返回給用戶的情況時,我總是想要將抽象類轉換爲具有內部「策略工廠」的具體類,以便用戶可以將實現類型傳遞給構造函數並直接與基類一起使用。何時隱藏具體類中的繼承層次結構?
我注意到.Net框架選擇以這種方式實現Socket(而不是創建一個在構造時傳遞SocketType的DatagramSocket)。什麼是一些指導方針來決定什麼時候可以將層次結構扁平化爲這樣的單個具體類?
每當我遇到一個工廠基於某些「低級」類型參數(如協議或外部資源的格式)將抽象基類實現返回給用戶的情況時,我總是想要將抽象類轉換爲具有內部「策略工廠」的具體類,以便用戶可以將實現類型傳遞給構造函數並直接與基類一起使用。何時隱藏具體類中的繼承層次結構?
我注意到.Net框架選擇以這種方式實現Socket(而不是創建一個在構造時傳遞SocketType的DatagramSocket)。什麼是一些指導方針來決定什麼時候可以將層次結構扁平化爲這樣的單個具體類?
我認爲這一點是:「客戶應該瞭解多少底層細節?」。
如果您選擇第一個解決方案(抽象基類),您將隱藏更多詳細信息給客戶端類。這樣客戶端可以完全忽略低層細節(協議,外部資源的格式)。當目標是完全隱藏實現細節和在實現中使用的類型時,我更喜歡這種方法。否則,如果客戶端已經知道低層實現的一些細節(例如客戶端知道他將使用的套接字是UDP並且他也想知道那種信息),那麼抽象基類的方法可以被內部的「戰略工廠」所取代。
本着'偏好合成而非繼承'的精神,我總是選擇策略+工廠方法而不是繼承。這給了我幾個優點: *大多數情況下,每個策略都可以獨立測試,而無需關心將使用它的類。 *以同樣的方式,客戶端類可以用模擬策略進行測試 *可以將策略設計爲可合成的,例如使用裝飾器模式,這可以提供很大的靈活性,而不會導致子類爆炸。總之,如果所有子語句的外部語義是相同的(如它應該那樣),請遵循策略路線。