本篇介紹軟件設計原則之一DIP:依賴倒置原則。不少知識回頭來看會有新的理解。看到一句話,一段文字,一個觀點有了新的理解,醍醐灌頂的感受。這種感受像是一種驚喜。古語說:溫故而知新。git
DIP:依賴倒置原則github
a.高層模塊不該該依賴於低層模塊。兩者都應該依賴於抽象。web
b.抽象不該該依賴於細節。細節應該依賴於抽象。微信
層次化架構
Booch曾經說過:「全部結構良好的面向對象架構都具備清晰的層次定義,每一個層次經過一個定義良好的、受控的接口向外提供了一組內聚的服務」app
倒置的接口全部權框架
這裏的倒置不只僅是依賴關係的倒置,它也是接口全部權的倒置。咱們一般會認爲工具庫應該擁有它們本身的接口。可是當應用了DIP時,咱們發現每每是客戶擁有抽象接口,而它們的服務者從這些抽象接口派生。工具
依賴於抽象spa
該啓發式規則建議不該該依賴於具體類——也就是說應該終止於抽象類或接口。架構設計
咱們在應用程序中所編寫的大多數的類是不穩定的。咱們不想直接依賴於這些不穩定的具體類。經過把它們隱藏在抽象接口的後面,能夠隔離它們的不穩定性。但這不是一個完整的解決方案,經常,若是一個不穩定的接口必需要變化時,這個變化必定會影響到表示該類的接口。這種變化仍是破壞了由抽象接口維繫的隔離性。若是看得更遠一些,認爲是由客戶模塊或層來聲明它們須要的服務接口,那麼僅當客戶須要時纔會對接口進行改變。這樣,改變實現抽象接口的類就不會影響到客戶。
那麼咱們來聊下咱們應用中經常使用的架構類型,微軟爲了展現.Net企業系統開發的能力。曾經發布過一個PetShop做爲範例,後來不少企業系統的架構都採用了參照了或簡化了此架構設計。標準的三層架構。
從上圖所知,業務層對數據訪問層抽象出來的IDAL模塊,除了解除了向下的依賴以外,對於其上的業務邏輯層,相同僅存在弱依賴關係。那麼來看這個設計知足了DIP:依賴倒置原則的高層模塊不該該依賴於低層模塊,兩者都應該依賴於抽象。 傳統的軟件開發,好比結構化分析和設計,老是傾向於建立一些高層模塊依賴於低層模塊、策略依賴於細節的軟件結構。實際上這些方法的目的之一就是要定義子程序層次結構,該層次結構描述了高層模塊怎麼調用低層模塊。一個設計良好的面向對象程序(如上圖所示的Petshop ),其依賴程序結構至關於傳統的過程式方法設計的一般結構而言就是被「倒置「了。
那麼IDAL接口層的全部權屬於誰的?之前一直有這個疑問直到看到這一章疑問解決了。一般認爲IDAL接口層屬於DAl層,那是不對的。這裏的IDAL接口層的全部權是屬於BLL層了,接口全部權倒置了。經過倒置這些依賴關係,咱們建立了一個更靈活、更持久、更易改變的結構。高層模塊BLL不在直接依賴DAL層,而依賴抽象IDAL接口層。則層與層之間的關係就是鬆散耦合的。假設此時必需要改動數據訪問層的實現,僅僅從新實現IDAL的接口定義,那麼業務邏輯層就不會受到影響。畢竟,不管是SQLServerDAL仍是OracalDAL與業務邏輯層實現沒有直接的關係。
面象對象的程序設計倒置了依賴關係,使得細節和策略依賴於抽象,而且經常是客戶擁有服務接口。依賴關係的倒置正是好的面向對象設計的標誌所在。是實現許多面向對象技術所宣稱的好處的基本低層機制。它的正確應用對於建立重用的框架來講是必需的。同時它對於構建在變化面前富有彈性也是重要的。因爲抽象和細節彼此隔離,因此代碼也很是容易維護。
其實最深的體會是對接口全部權倒置的理解。
代碼示例地址:https://github.com/tianyaxiang/ApplicationArchitecture
本文首發於我的微信公衆號:webguan ;歡迎您的關注