Agile Principles, Patterns, and Practices in C# 無瑕的程式碼 敏捷完整篇 第11章 DIP:依賴反向原則
第十一章內容是DIP (The Dependency-Inversion Principle):依賴反向原則 ,可與《Clean Code》第十一章對照看,C#範例可幫助讀者了解C#如何做到DIP。
DIP (The Dependency-Inversion Principle):依賴反向原則
高層模組不應該依賴低層模組,兩者都應該依賴於抽象。
抽象不應該依賴於細節,細節應該依賴於抽象。
圖7-1Copy程式是高層模組依賴低層模組的典型範例。
低層模組的變動會影響高層模組,我們希望能夠重複使用高層模組,要讓高層模組獨立於低層模組。
層次化 (Layering)
比較圖11-1與圖11-2 可了解有沒有反向的差別。圖11-1牽一髮動全身,圖11-2 解除了高層對低層的依賴關係。
反向的介面所有權
反向不只是依賴關係反向,介面所有權也會反向。
依賴於抽象
程式中所有的依賴關係,都應該終止於抽象類別或介面。
任何變數都不應該持有一個指向具體類別的參考
任何類別都不應該從具體類別衍生出來
任何方法都不應改寫「基底類別中已經實作的方法」
作者又說會有例外狀況,有時候必須要建立具體類別的實例,而建立這些實例的模組會依賴它們。
編者補充C#可用字串建立類別解這個問題,可把具體類別的名子作為configuration data 傳送給程式。
還有一種情況是具體類別不太會改變,例如C#的 String 類別。
簡單的DIP範例
依賴反向可應用在「任何存在一個類別向另一個類別發送訊息」的地方。
圖11-3 與Listing 11-1 描述簡單的按Button 開關燈的程式,明顯違反DIP。
找出潛在的抽象
不隨具體細節改變而改變的真理,它是系統內部的系統隱喻(metaphore)。
圖11-4是改良後的結果,遵守DIP。 「開燈」與「關燈」是範例中的隱喻(metaphore)。
熔爐案例
Listing11-2是原始程式。程式直接使用 in() 與 out() 控制溫度,違反DIP。
圖11-5 與 Listing11-3 是改良後的程式。新增Thermometer介面與Heater介面完成依賴反向。
總結
依賴反向是物件導向設計的特色所在。抽象與細節隔離,程式易於維護。
留言
張貼留言