Agile Principles, Patterns, and Practices in C# 無瑕的程式碼 敏捷完整篇 第12章 ISP:介面隔離原則

       第十二章內容是ISP:介面隔離原則,看範例可以比較快了解ISP。


ISP (The Interface Segregation Principle) : 介面隔離原則


不應該強迫客戶程式依賴它們未使用的方法。


如果強迫客戶程式依賴它們不使用的方法,客戶程式會面臨「未使用方法變更」而帶來變更,因此希望隔離介面。


介面污染


參考Listing 12-1與Listing 12-2 ,要做一個安全門超時會通知的專案。


圖12-1是常見的解決方案。


Door類別依賴TimerClient,然而並不是所有的Door都需要定時功能,所有衍生類別必須提供TimeOut方法的退化實作,有可能違反LSP。


Door衍生類別不使用TimerClient類別,也必須要import 它,產生不必要的複雜性與不必要的重複。


為了增加新功能基底類別一直新增新的方法,會讓介面變胖。


分離客戶就是分離介面


使用者迫使介面改變,Door介面與TimerClient介面是兩群不同的使用者,既然客戶程式分離,介面也應該分離。


TimerClient有修改也會影響到Door與Door所有客戶程式。


類別介面與物件介面


如何讓兩個分離的介面在同一個物件中實作,才能遵守ISP? 物件不必透過物件的介面存取,可透過委託或物件的基底類別存取。


使用委託來分離介面


參考圖12-2與 Listing12-4 ,建立一個衍生自TimerClient的物件,並把物件的請求委託給TimedDoor。


這種方法遵循ISP,並且避免Door與Timer之間的耦合。


缺點是想要註冊一個超時請求時,都要去建立一個新物件。委託會花費一些執行時間與記憶體。


使用多重繼承來分離介面


參考圖12-3與 Listing12-5 ,利用多重繼承來遵循ISP原則。TimedDoor同時繼承Door和TimerClient。


作者建議優先使用這個方案。


ATM使用者介面的例子


圖12-5是未改良前的結構,若是要新增PayGasBillTransaction,必須要改動UI介面,也會影響到其他功能的程式。


圖12-6是改良後的結構,作者採用多重繼承來分離介面。


檢查圖12-6,為了達到Listing12-7介面初始化,建構每個事務的時候得到特定的UI版本。C#中會把所有UI放到一個單一類別如Listing12-8。 UIGlobals類別把我們千辛萬苦分開的介面又結合在一起。


函數g想要存取DepositUI又要存取TransferUI,用兩個參數的寫法較佳


    void g(DepositUI depositUI, TransferUI transferUI)


之後???????????????????? Listing12-9這段內容看不太懂


總結


過胖的類別會讓客戶程式之間產生不正常且有害的耦合關係。


客戶程式應僅僅依賴於它們實際呼叫的方法。


可使用多重繼承來分離介面


 



留言

這個網誌中的熱門文章

異世界NTR web版第三章 觀後感 喧賓奪主 ,反派實力過強

持有縮小技能的D級冒險者,與聖女結婚並加入勇者團隊 漫畫 01-04 觀後感 大我與小我

泛而不精的我被逐出了勇者隊伍 web第三章 觀後感 菲莉真能打; 露娜超爽der