從三層架構邁向領域驅動設計

三層架構

 

嚴格分層架構模式的特點是上層只能訪問相鄰的下層,其他層次間的調用都不允許。三層架構就是一種嚴格分層模式,它把職責劃分爲界面展示、業務邏輯、數據訪問三層,還有一個業務實體,前面三層都要依賴它,所以它並不構成一個層。

 

三層架構的特點是一種面向過程的編程思想,特點如下:

a. 業務實體類中基本上只有屬性沒有方法。

b. 業務邏輯層的類基本上只有方法沒有屬性。

c. 將數據表結構映射爲業務實體類是一個慣用做法,以至於有人將其稱之爲“傳統”。這樣的好處是只需要理解一套模型,能夠通過自動化工具從數據表直接生成業務實體,還能夠自然而然的通過自動化機制存儲與檢索業務實體。但對於複雜點的業務,這樣做就是絕大部分問題的根源。

d. 當業務膨脹起來,需要劃分模塊的時候,我們有個常用的變形:提取一個服務層出來,用來組合模塊間的交互,還爲業務邏輯層提供了一個防腐層,可以把記錄日誌、驗證權限、處理異常等職責分配給服務層。

 

 

由於採用了嚴格分層模式,用戶界面層是絕對不能跨過業務邏輯層調用數據訪問層的,同理服務層也是不能調用數據訪問層。但是圖2都有四層了。

其實三層架構還有個更準確的名字----分層貧血領域模型架構,前面名字中的領域模型指的是業務實體,貧血意思業務實體中沒有或很少方法。

 

三層架構的反思

三層架構的最大問題在於:實際應用中人們喜歡把內存模型和數據庫模型保持一致。三層架構的大部分問題都是從這裏衍生出來的。

數據庫模型的粒度如果很小,那麼大量的表連接很快就會讓數據庫跑不動了。

如果數據庫模型的粒度如果很大(這是大部分項目的選擇),代碼的質量(重用性、穩定性、擴展性)就很差。由於沒有從業務的角度去仔細定義每一個對象,每個人會根據自己的需要建立各種QueryModel或ViewModel,慢慢地類會多到想哭。

還有一些三層開發人員最終患上了數據庫癡迷症,他堅信程序就應該做個搬運工,其他的事情都應該交給數據庫來完成,業務邏輯也應該寫進存儲過程裏面去。

 

 

三層分層到DDD分層的轉變過程

優化三層結構&重構到面向對象的設計

 

由於目前的服務層職責是非常輕的,甚至有很多空殼的調用,所以平衡一下職責,把調用數據訪問層的職責從業務邏輯層提升到服務層,需要的數據通過參數傳遞給業務邏輯層。這樣,對於那些簡單到無業務邏輯的CRUD就不需要去訪問業務層了,直接調用數據訪問層。

結構如圖3,我們看到業務邏輯與數據訪問層已經沒有依賴關係了。

然後我們就可以把業務邏輯與業務實體移到一塊。

然後把屬於業務實體的邏輯遷移到實體類中。

 

圖4基本上就是圖3的各個層換了名字,並且UI可以訪問基礎設施層。而圖4與圖5的區別在於,圖4是基礎設施依賴領域層,圖5是領域層依賴基礎設施層。

 

 

DDD各層次職責解析

 

用戶界面層:

原版----負責向用戶展現信息以及解釋用戶命令。

補充---- MVC中V和C都屬於UI層,V展現信息,C解析用戶命令。UI像地圖一樣把各個控制器關聯了起來。

 

應用層

原版----很薄的一層,用來協調應用的活動。它不包含業務邏輯。它不保留業務對象的狀態,但它保有應用任務的進度狀態。

補充----協調應用的活動這句話太抽象了,我充實一下它:從數據訪問中獲取領域對象,調用領域對象的方法完成任務,然後再調用數據訪問代碼把領域對象的改變持久化。事務、權限檢查、記錄日誌、處理異常的職責也歸它管。這點和前面三層的服務層的職責其實是一樣的。

 

領域層

原版----本層包含關於領域的信息。這是業務軟件的核心所在。在這裏保留業務對象的狀態,對業務對象和它們狀態的持久化被委託給了基礎設施層。

補充----業務對象的持久化工作我們已經提升到應用層了,一般情況下,這層最好不要涉及資源庫的調用,但是並不絕對。資源庫的抽象要麼在領域層中,要麼提升到了“應用程序框架”,領域層是不會依賴基礎設施的。

 

基礎設施層

原版----本層作爲其他層的支撐庫存在。它提供了層間的通信,實現對業務對象的持久化,包含對用戶界面層的支撐庫等作用。

 

 

對比三層分層與DDD分層

a. UI層技術基本一樣,一些比較智能的綁定可能無法進行了。

b. 服務層基本一樣。

d. 業務實體+業務邏輯 = 領域層

e. 如果三層架構不採用業務實體與數據表一致的做法,這層也是一樣。由於內存結構與數據表結構之間存在阻抗失配,存取領域對象沒那麼簡單。

 

參考資料

《領域驅動設計精簡版》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章