一、引子
不知今年吹了什么風,忽然DDD領域驅動設計進入大家視野。該思想源於2003年 Eric Evans編寫的“Domain-Driven Design領域驅動設計”簡稱DDD,Evans DDD是一套綜合軟件系統分析和設計的面向對象建模方法。剛好公司領導強力推薦這個,抱着學習的心態,耗時5個月,體驗了一把:“DDD從入門到棄坑”。
二、思想
學習網站:https://www.jdon.com/ddd.html
書:領域驅動設計
2.1 服務器后端發展三個階段
服務器后端發展三個階段:
- 面向過程腳本:初始簡單,業務復雜后,維護難度指數上升。-->基本不為主流使用
- 面向數據庫表:初始難度中,業務復雜后,維護難度延遲后再指數上升。--->目前市面上主流
- 面向業務模型:DDD+SOA微服務的事件驅動的CQRS讀寫分離架構:應付復雜業務邏輯,以聚合模型替代數據表模型,以並發的事件驅動替代串聯的消息驅動。真正實現以業務實體為核心的靈活拓展。初始難度高,業務復雜后,維護難度線性上升(已很不錯)。
2.2 DDD最大特點
DDD革命性在於:領域模型准確反映了業務語言,而傳統微服務數據對象除了簡單setter/getter方法外,沒有任何業務方法,即失血模型,那么DDD領域模型就是充血模型(業務方法定義在實體對象中)。
三、落地
3.1 領域模型設計
以渠道中心(一個微服務)作為例子來做領域模型設計,核心就是設計2個圖,一個是戰略設計圖(宏觀) ,一個是戰術設計圖(細節)。
1.領域戰略設計圖
戰略設計圖是從一個限界上下文的角度出發去分析業務場景。主要是宏觀上的核心域、子域、實體關系圖。demo如下圖:
2.領域戰術設計圖
戰術設計圖是從一個限界上下文的角度出發去分析業務場景。細化到核心業務字段、領域實體、值對象、領域服務、領域事件等等。基本上這個圖畫完,代碼已經知道怎么寫了。demo如下圖:
3.2 技術實現
整體項目框架分層圖如下所示:
如上圖,4層典型DDD分層結構,
1.展現層:controller層。無業務邏輯
2.應用服務層:此層可以包含查詢邏輯,但核心業務邏輯必須下沉到領域層。
3.領域服務層:業務在這里組裝。倉儲(資源庫)接口在此層定義。
4.基礎設施層:倉儲(資源庫)實現層+PO持久化層。
注:
1.簡單查詢不涉及業務,是可以直接從應用層直接穿透到PO查詢,不需要經過domain層。如下圖所示,DDD本身是不限制非業務類操作跨層調用的。
2.DTO是不能存在於domain層的,DDD設計不認為DTO是業務對象,entity才是。或者傳值簡單數據類型也是可以的。
3.2.1 服務調用問題
1.域內調用
領域內調用,隨便調用,絲般順滑。至於實現,可以由一個核心域的倉儲實現層(第四層)去實現多個Repository接口。(比如這里A是核心域的實體名,B是支撐域、通用域等)
2.跨域調用
跨域分為
- 1.同上下文跨域:ACL層->Adapter適配器層→調用其它域的repository。--->不得已才使用,不推薦使用。
- 推薦:1.使用領域事件 eventbus來做解耦
- 2.跨上下文(肯定跨域):ACL層->Adapter適配器層->feign調用
3.2.2 包結構
包結構如下:
展開包結構如下:
展現層:Controller,僅做接口的入口定義和編排轉發,不做任何的業務處理;
應用服務層:application,負責接口參數DTO的簡單校驗,以及DTO和實體值對象的數據轉換,對於簡單的業務,也可以在應用層加載實體直接執行實體行為方法;
領域層:
- 模型:根據領域模型分析領域內各實體、聚合、聚合根、值對象等,這些對象在*.domain.model定義,實體內的行為方法只負責維護實體自身的生命周期和狀態;
- 行為:領域內各實體、聚合、聚合根等,會有相應的行為,在*.domain.model包下定義行為方法;
- 領域服務:領域提供的接口服務,需要定義在*.domain.service包下,業務相關的前置業務判斷、多個實體或值對象的行為邏輯處理等,都在領域服務中實現,需要注意的是並不是每個實體都有一個對應的領域服務,但是依賴多個實體的行為方法,最好根據這個業務模塊是建立一個領域服務;
- 倉儲:領域服務或上層應用服務需要使用到的基礎設施層,包括DB、Feign調用等,定義在*.domain.repository下,在*.infrastructure.repository下實現;
適配層:在acl包下的feign定義依賴外部的接口,並在acl的adapter包編寫轉換,由倉儲層操作實體時調用;
持久層:與常用DAO定義一致,由倉儲層操作實體時調用。
3.2.3 技術架構
目前業內沒有標桿,github開源地址:https://github.com/jovezhao/nest 。作者不是本人哈,這個項目可以練手DDD。
四、總結
DDD可以嘗試,但不建議主流業務硬上。建議淺嘗即止。(據我所知,業內連阿里巴巴都沒有大面積推廣。)