1. 程式人生 > >.NET應用架構設計—面向查詢的領域驅動設計實踐(調整傳統三層架構,外加維護型的業務開關)

.NET應用架構設計—面向查詢的領域驅動設計實踐(調整傳統三層架構,外加維護型的業務開關)

閱讀目錄:

  • 1.背景介紹
  • 2.在業務層中加入核心領域模型(引入DomainModel,讓邏輯、資料有家可歸,變成一個完整的業務物件)
  • 3.統一協調層Application Layer(加入協調層來轉換DomianModel)
  • 4.從資料扁平結構轉換成OO體系結構(使用OO豐富程式碼結構)
  • 5.DomainModel中的內容(帶開關的Specification、SOA化的Specification)
  • 6.模式、重構、單元測試在領域模型中的運用

1.背景介紹

由於時間關係廢話不多扯了,直奔主題,對領域驅動設計不是太瞭解的朋友請先熟悉相關主題或參考本人以下兩篇文章:

DomainModel是由很多細粒度的Object組成,按照以往的教訓(將Object行為、資料肢解,得到一個殘缺的Object),現在我們將邏輯行為和資料繫結在一起,形成了一個豐富的領域模型,這也是面向物件設計原則之一;想了解更多關於實現面向物件的技巧請參考【《實現模式》作者:Kent Beck】

一書;

但是這樣又帶來了由於充血型DDD模型會給面向大規模查詢的業務模組帶來一定的效能開銷,試想一個OrderManager物件,如果我們需要獲取在某個條件範圍類的所有Order會給OrderManager帶來很多效能、邏輯上的複雜度;根據DDD.CQRS架構,得知將DomainModel中的查詢邏輯單獨剝離出去,讓Command端很乾淨的處理聚合的寫邏輯,在Query端也很直接的處理查詢邏輯;

這樣設計之後會有一個很尷尬的情況,在Query端的DomainModel不被關注了,因為Query的邏輯有簡單有複雜,大型站點會有很多複雜的查詢邏輯還會有很多的業務開關,做過維護的朋友應該知道新功能上線需要有switch的控制,這是為了安全起見吧;但是簡單的業務邏輯就會被我們下意識的認為不需要使用完整的DomainModel結構,還是使用傳統的分層架構上層依賴下層,Business Layer直接依賴DataAccess Layer,其實這個時候Business Object已經不在是遵循“單一職責”原則了,這樣時間一長又慢慢的回到了以前肢解Object的困境;

這篇文章是講解如何在Query端實踐DDD,如何運用DDD的強項來解決複雜業務邏輯的實現,尤其是複雜的業務邏輯需要開關控制的時候其實更需要DomainModel來完成;

2.在業務層中加入核心領域模型(引入DomainModel,讓邏輯、資料有家可歸,變成一個完整的業務物件)

由於我們缺乏領域模型,所以導致我們的業務邏輯、規則隨波逐流,無家可歸,時間久了就搞不清到底這塊業務邏輯是哪裡的;我們現有的Domain Model是一個數據對映物件用來傳遞資料用的,嚴格意義是一個DTO物件,大部分的專案都將DTO命名為DomainModel但是其實裡面沒有任何的行為、方法,只是一個純粹的資料傳輸用的容器,所以稱不上DomainModel;

所以我們首先要做的就是加入DomainModel,然後逐漸將邏輯搬移到DomainModel中來,在進行逐步的重構、單元測試,讓其成為一個可以測試的具有一定核心價值的可重用的DomainModel;

3.統一協調層Application Layer(加入協調層來轉換DomainModel)

我們的Service沒有Application Layer  也稱協調層,專門用來組裝業務處理環節的統一排程中心,它並非只是一個簡單的靜態類;傳統三層中沒有應用層的概念或者說應用層的概念沒扭曲了,或者並沒有發揮其的核心作用;我們需要加入應用層來協調DomainModel的工作;

4.從資料扁平結構轉換成OO體系結構(使用OO豐富程式碼結構)

當我們使用DTO物件成功將資料從資料來源獲取之後,就需要一個物件化的過程,將扁平化的資料實體轉換成豐滿的領域模型,這個時候所有的領域規則將起作用;

5.DomainModel中的內容(帶開關的Specification、SOA化的Specification)

1.實體:

簡單理解為OO物件,可以獨立存在也可以聚合在某個領域實體下,如果聚合在某個實體下那麼只能通過父級實體進行一系列的訪問;

2.工廠:

對實體進行有相關約定的建立,這其中包括各種驗證、約束、開關等等前提條件。注意:建立實體不像建立資料DTO那麼簡單;

3.規約、規約工廠:

對業務規則進行物件化,將原本淹沒在雜亂無章程式碼中的核心業務規則提取出來統一管理;這可以很好的像規則配置化(專業稱:規則外掛);注意:這可以和我們的業務開關進行合併;最值得驚喜的是可以通過規約工廠來實現面向SOA的規約;

4.領域事件(擴充套件):

監控、觀察等等非侵入式的獲取實體在業務處理當中的狀態資料,如:傳送一封郵件、記錄一條LOG,但是這種程式碼嚴禁寫入業務邏輯層包括分層架構中的任何一個層面,它必須是在一個無關緊要的宿主中進行,類似管道模型的Module;

5.面向特定業務開關:

由於我們每次新增或修改業務邏輯都會加入相應的開關控制,如果這個開關是和業務邏輯相關的那麼就可以很巧妙的和規約合併設計;

6.模式、重構、單元測試在領域模型中的運用

設計模式的運用:通過運用DDD就可以方便的對Domain Model進行設計模式的強粒度運用;

重構的運用:對領域模型進行重構就不需要考慮業務邏輯會影響到其他層面;

單元測試的運用:可以獨立對領域模型進行測試,包括細粒度的介面抽取都會很方便;