DDD領域驅動設計通常會包含戰略設計和戰術設計兩部分:
戰略設計:重業務建模,以業務視角,拆分領域,通過事件風暴(從發散到收斂過程),梳理業務並構建領域模型,這塊過程會涉及業務人員、產品人員、架構師等多方參與;
戰術設計:重落地實現,以構建的領域模型,建立了領域模型的邊界與上下文,也就確認了微服務的邊界,這個過程會涉及架構師、技術人員參與;
下面的圖展示了DDD設計開發的一般步驟和涉及到的戰略設計和戰術設計相關的概念與要素:
分析方法:
用5W2H進行分析:
用戶(WHO)在什么環境(WHERE)下遇到什么時機(WHEN)因為什么(WHY)產生什么目標(WHAT),繼而通過什么方法(HOW)去達成目標。
四色原型:
時刻-時段原型(Moment-Interval Archetype,簡稱MI):一段時間內發生的業務,包括與業務相關的數據以及行為。使用粉紅顏色表示。
角色原型(Role Archetype):任何一個系統都需要某種人或某種組織介入運行,例如:論壇系統需要注冊者角色發言。使用黃色標識。
參與方-地點-物品原型(Part-Place-Thing Archetype,簡稱PPT):表示參與不同角色的參與方、或者地點、或者事物。其中,Part表示有自主行為的,例如:人;place、thing表示沒有自主行為,如:某個地方或者事物,具體如“商品可以在不同場景扮演不同的角色”。使用綠色表示。
描述原型(Description Archetype,簡稱DESC):Desc是對PPT的抽象概括或總結。例如:一個人可以用身份證號碼、身高、體重、喜好來概括描述。用藍色表示。
事件風暴:
是一項團隊活動,是一種快速探索復雜業務領域和對領域建模的實踐。旨在通過領域事件識別出聚合根,進而划分微服務的限界上下文。
具體方式:
在活動中,團隊先通過頭腦風暴的形式羅列出領域中所有的領域事件,整合之后形成最終的領域事件集合,然后對於每一個事件,標注出導致該事件的命令(Command),再然后為每個事件標注出命令發起方的角色,命令可以是用戶發起,也可以是第三方系統調用或者是定時器觸發等。最后對事件進行分類整理出聚合根以及限界上下文。
概念說明:
命令是外部的一些操作和業務行為,也是微服務對外提供的能力。
領域事件是領域模型的組成部分,表示領域中所發生的事情,對業務有價值,即在同一個領域中其他部分知道並產生后續動作的事件。
以寵物為例:
如果做為寵物主人,你的問題域是如何養好一只貓,那么是不是已經打了疫苗,給寵物飼喂食物等將成為你關注的事情。領域事件會有:疫苗已注射,貓糧已飼喂等。
如果你是寵物醫生,問題域是如何治好寵物的病,關注的事情是寵物的身體構成,准確的診斷寵物病情,對症下葯。領域事件會有:病情已確診,葯方已開治。
雖說二者關注的都是寵物,在不同的問題域下領域事件是不同的。
案例分析:
案例1、通過“燃氣繳費”案例結合"5W2H分析法"和"四色原型"來描述DDD建模過程:
“燃氣抄表計費場景每月末,燃氣公司制定抄表計划並批量生成抄表任務,抄表任務通過工單的形式下發到抄表人員到客戶現場抄表,抄表完成之后給客戶應收賬單,客戶可以現場繳費或者延后通過在線自助繳費。下面以此案例描述建模步驟。”
對比
案例2、“請假考勤”采用“事件風暴”建模過程:
“請假人填寫請假單提交審批,根據請假人身份、請假類型和請假天數進行校驗,根據審批規則逐級遞交上級審批,逐級核批通過則完成審批,否則審批不通過退回申請人。根據考勤規則,核銷請假數據后,對考勤數據進行校驗,輸出考勤統計。”
具體步驟:
1、業務場景描述:
案例1、獲得“需求場景清單”;
VS
案例2、事件風暴的第1步,獲得“產品願景”。產品願景是對產品頂層價值設計,對產品目標用戶、核心價值、差異化競爭點等信息達成一致,避免產品偏離方向。
在線請假考勤系統,從產品願景中可以明確項目目標和關鍵功能,與競品(HR)的關鍵差異以及自己的優勢和核心競爭力等。
2、業務流程梳理:串聯業務場景采用“業務流程”進行描述;
3、尋找時標性對象:即可追溯的業務事件。將業務流程分解到業務過程。
這些時標性對象(用紅色標記)的關系描述出來,就得到了領域模型的骨干:
4、尋找時標對象周圍的“人、地、物”(即ppt):用綠色表示“時標對象周圍”的“人、地、物”
5、抽象“角色”:黃色表示。
6、補充“描述”信息:描述對象包括“人、地、物”和時標對象,用藍色表示;
VS
案例2、事件風暴的第2步,可以對標上面的2、3、4、5、6步驟。
做場景分析。場景分析是從用戶視角出發,探索業務領域中的典型場景,產出領域中需要支撐的場景分類、用例操作以及不同子域之間的依賴關系。如下圖:
7、 划分限界上下文:抄表繳費屬於核心業務,將業務過程中的時標對象都划分到核心子域
8、確定聚合及聚合根:在每個上下文中,對時標對象中的概念按照相近原則划分為不同的組,形成新的聚合,然后選出聚合根作為與外界交互的代表。 比如:抄表時標對象產出的核心數據是待繳費的應收賬單,關聯對象涉及到抄表員、客戶和表具,而其他暫時無法分組的概念或屬性獨立為值對象。淺綠色代表聚合根。
其他:
VS
案例2、事件風暴的第3、4、5步。第3步、找領域實體和值對象等領域對象;第4步、找出聚合根,根據實體、值對象與聚合根的依賴關系,建立聚合;第4步、根據業務及語義邊界等因素,定義限界上下文。
第3步:找出發起或產生這些命令或領域事件的實體和值對象,並將命令和事件聚集到實體。
第4步: 定義聚合。先找出聚合根(從上面的實體中,我們可以找出“請假單”和“人員”兩個聚合根),然后找出與聚合根緊密依賴的實體和值對象。我們發現審批意見、審批規則和請假單緊密關聯;組織關系和人員緊密關聯;還有刷卡明細、考勤明細和考勤統計,這幾個實體沒有聚合根,它們之間相互獨立,不是富領域模型,這時可以抽象一個聚合根,也可以直接放一起各自直接對外(而非聚合根來對外)。
第5步: 定義限界上下文。根據聚會的業務關聯性,分成不同的限界上下文。
人員組織關系聚合與請假聚合,共同完成請假的業務功能,兩者在請假的限界上下文內。考勤聚合則單獨構成考勤統計限界上下文。即建立請假和考勤兩個領域模型。
9、 優化調整子域划分:例如:客戶和表具在多個上下文中共用,是可以將其獨立出來,作為共享上下文,划分到通用子域中。繳費環節,因為支付通常作為基礎功能,也划分到獨立的支撐子域;
VS
案例2、事件風暴,也可調整建立的領域模型。
學習資料:https://www.jianshu.com/p/fbeaa3da6c43
https://cloud.tencent.com/developer/article/1837097