Java架構(gòu)設(shè)計之六步拆解 DDD
引言
相信通過前面幾篇文章的介紹,大家對于 DDD 的相關(guān)理論以及實踐的套路有了一定的理解,但是理解 DDD 理論和實踐手段是一回事,能不能把這些理論知識實際應用到我們實際工作中又是另外一回事,因此本文通過實際的業(yè)務分析把之前文章中涉及的理論和手段全部帶著大家走一遍,我想通過這種方式,讓大家實際的感受下 DDD 落地過程中會遇到哪些問題以及我們應該怎樣去解決這些問題。
項目需求信息
這里還是大家比較熟悉的電商場景來進行說明,我想這樣大家比較好理解一點。在前段時間雙十一,大家被各種購物優(yōu)惠券的套路整的眼花繚亂,仿佛數(shù)學不好,都不配拿到最優(yōu)惠的價格了。大家都在吐槽,就不能少點套路,買東西直接給我 5 折不就天下太平了嗎?我想造成這種現(xiàn)象的原因大概就是中國電商行業(yè)的內(nèi)卷吧,只有通過各種營銷活動的堆積,才能讓大家話更多的時間去瀏覽更過的商品,才能獲得更好的留客以及交易。好了,跑題了,這些我們先不去關(guān)心。那我們今天就用這個折磨人的優(yōu)惠券的流程作為設(shè)計實例來說明整個 DDD 的落地過程吧。優(yōu)惠券的關(guān)鍵業(yè)務流程如下:
(1)當需要進行大促活動的時候,運營同學需要選定對應的商品,創(chuàng)建創(chuàng)建優(yōu)惠券。
(2)運營同學需要創(chuàng)建營銷活動,制定對應的營銷活動規(guī)則,比如什么滿減啊,跨店減啊類似這種折磨人腦細胞的規(guī)則,然后關(guān)聯(lián)相應的優(yōu)惠券,最后提交活動審批。審批通過后,進行營銷活動發(fā)布。
(3)提交活動審批后,審批進行營銷活動審批。
(4)用戶在營銷頁面領(lǐng)取優(yōu)惠券之后,下單購買商品之后,在付款的時候根據(jù)對應的優(yōu)惠券進行付費金額計算并完成支付。
DDD 落地實踐
項目背景信息我們大致了解之后,那么我們就要著手開始通過DDD來進行領(lǐng)域驅(qū)動設(shè)計的過程了。其實我們學習 DDD 理論以及方法不是最終的目的,而通過它實現(xiàn)實際的業(yè)務復雜度治理以及優(yōu)化微服務設(shè)計才是真正的目的。
戰(zhàn)略設(shè)計
在戰(zhàn)略設(shè)計階段,我們最主要的過程大致包括了業(yè)務場景分析、領(lǐng)域建模、劃分邊界上下文三個階段。實際上戰(zhàn)略設(shè)計是 DDD 過程中的核心步驟。
1、業(yè)務分析
在這個階段我們所有做的就是進行全面的業(yè)務梳理,吧業(yè)務中涉及到的所有細節(jié)都梳理出來,為后續(xù)進行領(lǐng)域建模分析提供足夠的、全面的業(yè)務輸入。經(jīng)常使用到的業(yè)務場景分析方法主要包括用例分析法、事件風暴法以及四色建模法。這里我們使用事件風暴進行業(yè)務場景的分析以及梳理。
(1)事前準備
在進行事件風暴之前我們需要進行一些準備,主要包括貼紙、筆以及討論的會議室,會議室中最好不要有椅子,目的是想讓大家都能夠站立在一起、全神貫注的去進行業(yè)務討論。
(2)邀請參會的人
會議的參與方主要包括業(yè)務、用戶、PD、研發(fā)、測試、架構(gòu)師等。
(3)業(yè)務討論
首先確定我們今天需要討論的業(yè)務是什么,目標是什么。像前文所說的那樣,本次討論的業(yè)務就是營銷活動的優(yōu)惠券業(yè)務,目標就是完成優(yōu)惠券的業(yè)務梳理,確保沒有業(yè)務方面的理解 gap,在團隊中達成業(yè)務理解的的一致性。在這個過程中我們需要通過提問的方式來驅(qū)動交流。
a、分析業(yè)務中的事件,搞清楚事件發(fā)生的前因后果,什么意思呢?就是什么動作會導致當前時間的發(fā)生,當前這個事件發(fā)生后又會導致怎樣的后果。這些我們都需要梳理清楚。還有一點需要注意, 我不但要關(guān)注正常的業(yè)務流程還要關(guān)注異常的業(yè)務流程。
b、尋找業(yè)務邏輯和業(yè)務規(guī)則,比如我們在提交活動前,需要確定這些優(yōu)惠券適用哪些人、領(lǐng)取方式是怎樣的以及生效事件是怎樣的等等,這些都是我們在執(zhí)行操作之前需要確定的業(yè)務規(guī)則。
如下圖所示,我們將優(yōu)惠券的業(yè)務流程進行了梳理,分別從操作人、事件、命令的方式來描述整個優(yōu)惠券業(yè)務流轉(zhuǎn)的過程。
注:在進行事件風暴過程中,所有的參與人都要全身投入整個過程,放下手機以及電腦,一起參與整個業(yè)務梳理過程,只有這樣,事件風暴才可能有比較好的效果。
2、領(lǐng)域建模
在前面的事件風暴業(yè)務梳理中,我們已經(jīng)把優(yōu)惠券業(yè)務涉及到的參與者、動作以及事件等都進行了全面的梳理。那么接下來我們就要在此基礎(chǔ)之上進行領(lǐng)域建模,這是整個 DDD 的核心。
(1)領(lǐng)域?qū)ο蠓治?/h4>
如上面所示的事件風暴小黑板中的內(nèi)容,我們需要在這些梳理出來的內(nèi)容中找到對應的實體、值對象以及圍繞這些的領(lǐng)域事件以及命令操作。根據(jù)分析,我們總整個業(yè)務過程中提取了優(yōu)惠券、營銷活動、活動審批單、活動規(guī)則、審批意見等實體以及值對象以及和這些領(lǐng)域?qū)ο笙嚓P(guān)的命令操作。
(2)構(gòu)建業(yè)務聚合
完成領(lǐng)域?qū)ο蠓治鲋?,我們需要?gòu)建業(yè)務聚合。想要構(gòu)建聚合,那么首先就要在實體中找到聚合根。我們先來回顧下聚合根的特點,聚合根一定是實體,那么它具有全局唯一的標識,另外它是具備生命周期的同時需要專門的模塊來進行管理。根據(jù)這樣的標準,在領(lǐng)域?qū)ο笾形覀儼l(fā)現(xiàn)優(yōu)惠券、營銷活動以及活動審批單是具備聚合根特征的,而營銷規(guī)則、營銷內(nèi)容等是和營銷活動緊密相關(guān)的,因此他們構(gòu)成營銷活動聚合關(guān)系。優(yōu)惠券規(guī)則、優(yōu)惠券類型等是和優(yōu)惠券聚合根緊密相連的,所以他們構(gòu)成優(yōu)惠券聚合關(guān)系。同理活動審批單也會構(gòu)成聚合關(guān)系。最終我們形成如下的聚合關(guān)系。
3、劃分邊界上下文
在上述步驟中,我們獲得了整個業(yè)務流程中的所有聚合后,我們需要更具業(yè)務語義上下文將具體的聚合劃分到對應的上下文中,因此我們可以把優(yōu)惠券的業(yè)務分為優(yōu)惠券、營銷活動以及審批三個限界上下文。
戰(zhàn)術(shù)設(shè)計
在戰(zhàn)略設(shè)計階段,我們通過事件風暴法對整體的業(yè)務進行了全部的梳理,同時構(gòu)建了領(lǐng)域模型以及劃分了邊界下文。那么接下來我們就要將領(lǐng)域模型映射到工程結(jié)構(gòu)以及代碼中實現(xiàn)最終的實現(xiàn)落地。另外在這個階段實際還有很多細節(jié)需要明確,那優(yōu)惠券來說,它包含哪些屬性,需要哪些領(lǐng)域服務,哪些需要設(shè)計為實體,哪些需要設(shè)計為值對象,這些都是需要在戰(zhàn)術(shù)設(shè)計階段明確下來。
1、微服務拆分
我們根據(jù)已經(jīng)劃分的邊界上下文,我們可以拆分為優(yōu)惠券服務、營銷活動服務以及審批中心三個微服務,至于用戶支付使用這塊,還是由原先已存在支付服務來完成,只是在付款核算的時候需要使用到優(yōu)惠券進行最后的金額計算。
2、領(lǐng)域分層
在領(lǐng)域分層方面,我們還是按照之前文章中所說的分層結(jié)構(gòu)來進行,即 interfaces 層、biz 層、domain 層以及 instructure 層。每層代表的含義之前的文章中已經(jīng)進行了詳細的說明,大家可以翻看前面文章中的介紹,這里不再進行贅述了。
我們以優(yōu)惠券為例,實際聚合中對象還需要進行進一步的細化。對于優(yōu)惠券來說它實際上還有如下所示的值對象以及實體來組成實際的優(yōu)惠券。同時在優(yōu)惠券我們的梳理的領(lǐng)域服務還包括創(chuàng)建優(yōu)惠券、查詢優(yōu)惠券以及修改優(yōu)惠券狀態(tài),這些動作實際都應該在領(lǐng)域?qū)油ㄟ^領(lǐng)域服務的形式完成落地。而對應的 biz 層就相當于業(yè)務的編排組合,也就是實際的業(yè)務流程的串聯(lián)。
3、代碼結(jié)構(gòu)
當我們把領(lǐng)域?qū)ο筮M行進一步的細化之后,同時把對應的領(lǐng)域服務敲定之后,我們可以把這些分析后的內(nèi)容映射成工程分層后的代碼了。如下圖所示,即為優(yōu)惠券的 domain 層的代碼映射。
當然到這里并不意味著結(jié)束,其實在后續(xù)還有很多工作要做,比如詳細設(shè)計、編寫代碼以及功能測試,特別實在詳細設(shè)計階段,我們還要涉及很多的細節(jié)問題的敲定,比如數(shù)據(jù)庫表的設(shè)計、比如使用什么 MQ,用不用緩存,怎么保證緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性問題,分布式服務有沒有分布式事務的問題,應該怎么解決?有沒有服務冪等問題,應該怎么解決?這些都是需要在詳細設(shè)計階段進行確定的。因此 DDD 就像是框架,通過它把業(yè)務映射成為領(lǐng)域?qū)ο笠约邦I(lǐng)域服務和領(lǐng)域事件,再把這些領(lǐng)域相關(guān)內(nèi)容再讀映射為實際的代碼。使得我們的服務更加的邏輯清晰以及擴展性更強,但是分布式的技術(shù)實現(xiàn)細節(jié),我們還是需要有對應的解決方案來進行解決。
總結(jié)
本文以電商行業(yè)的營銷活動中的優(yōu)惠券的發(fā)放和使用作為實際案例來闡述 DDD 領(lǐng)域驅(qū)動設(shè)計落地實踐的過程,通過整個過程的梳理,為大家提煉了整個設(shè)計過程的精要,相信大家可以按照這樣的思路在實際的工作中再結(jié)合各自的業(yè)務特征應該可以真正完成整個 DDD 的實踐。萬事開頭難,相信只要大家能夠親自去參與或者主導一個 DDD 的落地實踐過程,那么對于理解 DDD 這套架構(gòu)設(shè)計方法論又會進入一個新的臺階。在后面的文章中再和大家聊聊落地 DDD 過程中可能會遇到的一些問題以及軟件復雜度治理的問題。
真正的大師永遠懷著一顆學徒的心 ————————————————
到此這篇關(guān)于Java架構(gòu)設(shè)計之六步拆解 DDD的文章就介紹到這了,更多相關(guān)Java 拆解 DDD內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
迅速學會@ConfigurationProperties的使用操作
這篇文章主要介紹了迅速學會@ConfigurationProperties的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Java中&&與?表達式結(jié)合時出現(xiàn)的坑
這篇文章主要給大家介紹了關(guān)于Java中&&與?表達式結(jié)合時出現(xiàn)的坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-02-02學會IDEA REST Client后就可以丟掉postman了
這篇文章主要介紹了學會IDEA REST Client后就可以丟掉postman了,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12淺析java中 Spring MVC 攔截器作用及其實現(xiàn)
本篇文章主要介紹了java中SpringMVC 攔截器的使用及其實例,需要的朋友可以參考2017-04-04使用springboot開發(fā)的第一個web入門程序的實現(xiàn)
這篇文章主要介紹了使用springboot開發(fā)的第一個web入門程序的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04Springboot Autowried及Resouce使用對比解析
這篇文章主要介紹了Springboot Autowried及Resouce使用對比解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06