領域驅動設計(DDD)之分層架構

 

前言

由於由近幾年微服務架構興起,領域驅動設計(DDD)也被大多領域專家重新看待。但是其實這兩者本來是不相關的兩個東西,2004年著名建模專家Eric Evans發表了他最影響力的書籍《領域驅動設計》,提了現在如日中天的架構設計方法論 — 領域驅動設計,核心思想是通過領域驅動設計方法定義領域模型,從而確定業務和應用邊界,保證業務模型與代碼模型的一致性。而微服務2014年橫空出世,由 Thoughworks 首席科學家 Martin Flower提出,微服務架構是一種架構模式,它提倡將單一應用程序劃分成一組小的服務,服務之間互相協調、互相配合,爲用戶提供最終價值。每個服務運行在其獨立的進程中,服務與服務間採用輕量級的通信機制互相協作

領域驅動設計更加強調的是一個架構設計方法論,所謂方法論的東西都是比較抽象並且很意識化,就像是建議你怎麼做,但不會可能覺得你做並做對了,但是在別人的認知上,你可能沒做,或者做的東西在認知水平上存在差異。而微服務是一種SOA演進的面向服務的系統架構,注重業務的垂直劃分,達到服務之間的職責單一明確。然而通過DDD 事件風暴、四色建模等得到的領域模型,模型上線文的邊界其實和微服務的邊界大體符合。甚至可以這麼說,採用 DDD 方法建立的領域模型,更能清晰地劃分微服務的邏輯邊界和物理邊界,好的領域驅動設計也就直接關係到微服務設計的水平,這就爲什麼微服務設計很多時候都是選擇DDD。所以領域驅動設計在微服務火起來的這幾年被重新認知,並有了很多結合微服務設計的DDD的系統落地。

由於DDD設計的理念偏廣,DDD名詞概念,DDD與微服務落地,DDD事件風暴及領域建模,DDD大中臺實踐,DDD與領域模型一致性等等話題,筆者這裏就DDD分層架構展開梳理,當然相應的其他模塊的知識有機會也會補上的

 

領域模型一旦確定,開發者都不期望代碼脫離模型分析確立的初衷。軟件維護的核心問題是軟件設計的完整性概念的維護,軟件變得難以維護的根本原因,在於模型概念完整性在軟件生命週期被破壞,並脫離分析模型的結果。在面向對象的程序中,有時候爲了可以容易將事情快速工作,用戶界面、數據庫邏輯以及其他聚合加工等代碼經常被直接寫在對象實體中。當領域相關邏輯被嵌入其它層,閱讀和維護這些代碼變得舉步艱難。表面上只是改用戶界面層的邏輯,卻變成了領域邏輯的調整。對業務的變更需要跟蹤從用戶界面,業務邏輯,甚至是數據庫層的邏輯,在某一處對代碼的簡單修改,都可能造成難以預測和不符合希望的結果,軟件細節調整需要大面積的軟件測試迴歸,自動化測試變得更加繁瑣,難以進行。

所以,需要對一個複雜的程序進行層次劃分,每一個層次內部進行內聚,單個層次依賴底下層次,解耦層次之間的業務邏輯交叉。將領域相關邏輯代碼聚集到某一層,用戶界面和數據庫等第三依賴組件隔離開來,領域相關操作只關心內部領域相關邏輯的實現,不再關注如何展示自己,如何保存自己,如何同步自己,如何解釋用戶命令等細節性工作。這會讓一個領域模型更加清晰,調整會回溯的成本隨着分層的合理性逐漸降低

 

傳統三層架構

互聯網早期,業務系統訴求相對簡單,很多時候CRUD已經滿足大部分場景,很多時候都不需要考慮併發,也不用估計業務快速發展帶來的系統複雜度和維護成本增加。傳統企業應用大多是單體架構,而三層架構成爲單體架構的一種常態。三層架構解決了程序內代碼間調用複雜、代碼職責不清的問題,但這種分層是邏輯概念,在物理上它是中心化的集中式架構,並不適合分佈式微服務架構。

三層架構
三層架構

層次解析

 

DDD四層架構

四層架構

 

事務管理比較有歧義,但是筆者還是將他放在應用層,當然,在

層次解析

 依賴倒置

 

三層架構如何演變四層?

 

DDD五層架構(DCI)

五層架構

 

六邊形架構

 

 

嚴格分層 VS 鬆散分層

看完上面的分層架構,你應該能很清楚的知道DDD在架構設計上的分層形式,筆者畫的圖很明顯可以看出架構層級依賴的單向性,也就是從上級層次到夏季層次。其實,領域驅動設計發展的過程中,也產生了一些依賴上的分歧:嚴格分層架構和鬆散分層架構。

在嚴格分層架構中,任何層只能與位於其直接下方的層發生依賴。在鬆散分層架構中,任何層可以與其任意下方的層發生依賴。這裏你應該可以理解,DDD 分層架構模型其實屬於嚴格分層架構,任何層只能對位於其直接下方的層產生依賴。而傳統的 DDD 分層架構更多的是屬於鬆散分層架構,允許某層與下方其任意層發生依賴。

 

 

時延性可能比較差 --》 鬆散分層

服務依賴關係,管理和維護 --》 嚴格分層

 

也嚴格分層 鬆散分層差別

優缺點及挑選,筆者認爲

實現領域驅動設計在分層架構上更加強調 “每層只能與位於其下方的層發生耦合”,


 

爲何DDD架構分層如此重要
 

 

番外:充血模型 VS 貧血模型

 

 

後記

最後還是有一些需要強調,可能你會很疑惑,從領域建模到微服務建設,到最後你落地時候發現,你定義的領域層成爲別人眼中的應用層,定義的應用層成爲別人看到的領域層。當然,這是完全有可能的,你看到的視覺是和你所從事的業務,負責的職責有關係,你們所看到的核心域、通用域和基礎域是完全不一樣的。比如你是負責訂單業務模塊,那麼訂單就是你的核心域,而用戶的賬戶相關業務相對你來說就是通用域。而反過來相對賬戶模塊的同學而言,他們設計系統對賬相關,總是需要檢索賬戶對應的所有訂單數據,達到用戶賬戶數據一致性,而你所在的訂單模塊也就成爲了賬戶模塊同學眼中的領域層了

此外,也並沒有哪一種分層架構是最優秀的,分層架構大到公司整體系統架構,小到代碼層次,都可以通過DDD領域建模,劃分領域上線文,建立領域內通用語言,面對不同的業務場景,團隊,文化,管理等因素,需要考慮的問題也就有所差別。選擇分層架構的時候,應該儘可能的從不同應用場景出發,選擇合適的架構分層

同時,領域模型不是一成不變的,因爲業務的變化會影響領域模型,而領域模型的變化則會影響微服務的功能和邊界。隨着業務發展,聚合重組和拆分會是一種常態。原來領域層的聚合,可能成爲應用程的業務控制模塊,業務控制模塊隨着限界上下文重新劃分,進入領域層。架構演進是一種動態迭代,並快速變化的過程,每個時刻,你看到的都是當時的業務系統的快照。

 

 

 

===

待續,待補充

===

 

 

 

 

 

 

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