天天看點

DDD 領域驅動設計落地實踐:六步拆解 DDD

作者:慕楓技術筆記

#頭條創作挑戰賽#

引言

相信通過前面幾篇文章的介紹,大家對于 DDD 的相關理論以及實踐的套路有了一定的了解,但是了解 DDD 理論和實踐手段是一回事,能不能把這些理論知識實際應用到我們實際工作中又是另外一回事,是以本文通過實際的業務分析把之前文章中涉及的理論和手段全部帶着大家走一遍,我想通過這種方式,讓大家實際的感受下 DDD 落地過程中會遇到哪些問題以及我們應該怎樣去解決這些問題。

項目需求資訊

這裡還是大家比較熟悉的電商場景來進行說明,我想這樣大家比較好了解一點。在前段時間雙十一,大家被各種購物優惠券的套路整得眼花缭亂,仿佛數學不好,都不配拿到最優惠的價格了。大家都在吐槽,就不能少點套路,買東西直接給我 5 折不就天下太平了嗎?我想造成這種現象的原因大概就是中國電商行業的内卷吧,隻有通過各種營銷活動的堆積,才能讓大家話更多的時間去浏覽更過的商品,才能獲得更好的留客以及交易。好了,跑題了,這些我們先不去關心。那我們今天就用這個折磨人的優惠券的流程作為設計執行個體來說明整個 DDD 的落地過程吧。優惠券的關鍵業務流程如下:

(1)當需要進行大促活動的時候,營運同學需要標明對應的商品,建立建立優惠券。

(2)營運同學需要建立營銷活動,制定對應的營銷活動規則,比如什麼滿減啊,跨店減啊類似這種折磨人腦細胞的規則,然後關聯相應的優惠券,最後送出活動審批。審批通過後,進行營銷活動釋出。

(3)送出活動審批後,審批進行營銷活動審批。

(4)使用者在營銷頁面領取優惠券之後,下單購買商品之後,在付款的時候根據對應的優惠券進行付費金額計算并完成支付。

DDD 領域驅動設計落地實踐:六步拆解 DDD

DDD 落地實踐

項目背景資訊我們大緻了解之後,那麼我們就要着手開始通過DDD來進行領域驅動設計的過程了。其實我們學習 DDD 理論以及方法不是最終的目的,而通過它實作實際的業務複雜度治理以及優化微服務設計才是真正的目的。

戰略設計

在戰略設計階段,我們最主要的過程大緻包括了業務場景分析、領域模組化、劃分邊界上下文三個階段。實際上戰略設計師 DDD 過程中的核心步驟,

1、業務分析

在這個階段我們所有做的就是進行全面的業務梳理,吧業務中涉及到的所有細節都梳理出來,為後續進行領域模組化分析提供足夠的、全面的業務輸入。經常使用到的業務場景分析方法主要包括用例分析法、事件風暴法以及四色模組化法。這裡我們使用事件風暴進行業務場景的分析以及梳理。

(1)事前準備

在進行事件風暴之前我們需要進行一些準備,主要包括貼紙、筆以及讨論的會議室,會議室中最好不要有椅子,目的是想讓大家都能夠站立在一起、全神貫注的去進行業務讨論。

(2)邀請參會的人

會議的參與方主要包括業務、使用者、PD、研發、測試、架構師等。

(3)業務讨論

首先确定我們今天需要讨論的業務是什麼,目标是什麼。像前文所說的那樣,本次讨論的業務就是營銷活動的優惠券業務,目标就是完成優惠券的業務梳理,確定沒有業務方面的了解 gap,在團隊中達成業務了解的的一緻性。在這個過程中我們需要通過提問的方式來驅動交流。

a、分析業務中的事件,搞清楚事件發生的前因後果,什麼意思呢?就是什麼動作會導緻目前時間的發生,目前這個事件發生後又會導緻怎樣的後果。這些我們都需要梳理清楚。還有一點需要注意, 我不但要關注正常的業務流程還要關注異常的業務流程。

b、尋找業務邏輯和業務規則,比如我們在送出活動前,需要确定這些優惠券适用哪些人、領取方式是怎樣的以及生效事件是怎樣的等等,這些都是我們在執行操作之前需要确定的業務規則。

如下圖所示,我們将優惠券的業務流程進行了梳理,分别從操作人、事件、指令的方式來描述整個優惠券業務流轉的過程。

DDD 領域驅動設計落地實踐:六步拆解 DDD

注:在進行事件風暴過程中,所有的參與人都要全身投入整個過程,放下手機以及電腦,一起參與整個業務梳理過程,隻有這樣,事件風暴才可能有比較好的效果。

2、領域模組化

在前面的事件風暴業務梳理中,我們已經把優惠券業務涉及到的參與者、動作以及事件等都進行了全面的梳理。那麼接下來我們就要在此基礎之上進行領域模組化,這是整個 DDD 的核心。

(1)領域對象分析

如上面所示的事件風暴小黑闆中的内容,我們需要在這些梳理出來的内容中找到對應的實體、值對象以及圍繞這些的領域事件以及指令操作。根據分析,我們總整個業務過程中提取了優惠券、營銷活動、活動審批單、活動規則、審批意見等實體以及值對象以及和這些領域對象相關的指令操作。

DDD 領域驅動設計落地實踐:六步拆解 DDD

(2)建構業務聚合

完成領域對象分析之後,我們需要建構業務聚合。想要建構聚合,那麼首先就要在實體中找到聚合根。我們先來回顧下聚合根的特點,聚合根一定是實體,那麼它具有全局唯一的辨別,另外它是具備生命周期的同時需要專門的子產品來進行管理。根據這樣的标準,在領域對象中我們發現優惠券、營銷活動以及活動審批單是具備聚合根特征的,而營銷規則、營銷内容等是和營銷活動緊密相關的,是以他們構成營銷活動聚合關系。優惠券規則、優惠券類型等是和優惠券聚合根緊密相連的,是以他們構成優惠券聚合關系。同理活動審批單也會構成聚合關系。最終我們形成如下的聚合關系。

DDD 領域驅動設計落地實踐:六步拆解 DDD

3、劃分邊界上下文

在上述步驟中,我們獲得了整個業務流程中的所有聚合後,我們需要更具業務語義上下文将具體的聚合劃分到對應的上下文中,是以我們可以把優惠券的業務分為優惠券、營銷活動以及審批三個限界上下文。

戰術設計

在戰略設計階段,我們通過事件風暴法對整體的業務進行了全部的梳理,同時建構了領域模型以及劃分了邊界下文。那麼接下來我們就要将領域模型映射到工程結構以及代碼中實作最終的實作落地。另外在這個階段實際還有很多細節需要明确,那優惠券來說,它包含哪些屬性,需要哪些領域服務,哪些需要設計為實體,哪些需要設計為值對象,這些都是需要在戰術設計階段明确下來。

1、微服務拆分

我們根據已經劃分的邊界上下文,我們可以拆分為優惠券服務、營銷活動服務以及審批中心三個微服務,至于使用者支付使用這塊,還是由原先已存在支付服務來完成,隻是在付款核算的時候需要使用到優惠券進行最後的金額計算。

2、領域分層

在領域分層方面,我們還是按照之前文章中所說的分層結構來進行,即 interfaces 層、biz 層、domain 層以及 instructure 層。每層代表的含義之前的文章中已經進行了詳細的說明,大家可以翻看前面文章中的介紹,這裡不再進行贅述了。

我們以優惠券為例,實際聚合中對象還需要進行進一步的細化。對于優惠券來說它實際上還有如下所示的值對象以及實體來組成實際的優惠券。同時在優惠券我們的梳理的領域服務還包括建立優惠券、查詢優惠券以及修改優惠券狀态,這些動作實際都應該在領域層通過領域服務的形式完成落地。而對應的 biz 層就相當于業務的編排組合,也就是實際的業務流程的串聯。

DDD 領域驅動設計落地實踐:六步拆解 DDD

3、代碼結構

當我們把領域對象進行進一步的細化之後,同時把對應的領域服務敲定之後,我們可以把這些分析後的内容映射成工程分層後的代碼了。如下圖所示,即為優惠券的 domain 層的代碼映射。

DDD 領域驅動設計落地實踐:六步拆解 DDD

當然到這裡并不意味着結束,其實在後續還有很多工作要做,比如詳細設計、編寫代碼以及功能測試,特别實在詳細設計階段,我們還要涉及很多的細節問題的敲定,比如資料庫表的設計、比如使用什麼 MQ,用不用緩存,怎麼保證緩存和資料庫的資料一緻性問題,分布式服務有沒有分布式事務的問題,應該怎麼解決?有沒有服務幂等問題,應該怎麼解決?這些都是需要在詳細設計階段進行确定的。是以 DDD 就像是架構,通過它把業務映射成為領域對象以及領域服務和領域事件,再把這些領域相關内容再讀映射為實際的代碼。使得我們的服務更加的邏輯清晰以及擴充性更強,但是分布式的技術實作細節,我們還是需要有對應的解決方案來進行解決。

總結

本文以電商行業的營銷活動中的優惠券的發放和使用作為實際案例來闡述 DDD 領域驅動設計落地實踐的過程,通過整個過程的梳理,為大家提煉了整個設計過程的精要,相信大家可以按照這樣的思路在實際的工作中再結合各自的業務特征應該可以真正完成整個 DDD 的實踐。萬事開頭難,相信隻要大家能夠親自去參與或者主導一個 DDD 的落地實踐過程,那麼對于了解 DDD 這套架構設計方法論又會進入一個新的台階。在後面的文章中再和大家聊聊落地 DDD 過程中可能會遇到的一些問題以及軟體複雜度治理的問題。

繼續閱讀