亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                DDD概念復(fù)雜難懂,實(shí)際落地如何設(shè)計(jì)代碼實(shí)現(xiàn)模型?

                DDD概念復(fù)雜難懂,實(shí)際落地如何設(shè)計(jì)代碼實(shí)現(xiàn)模型?

                今天我想與你聊一聊,DDD概念復(fù)雜、難懂,實(shí)際落地該怎么設(shè)計(jì)代碼實(shí)現(xiàn)模型。關(guān)于這個(gè)話(huà)題,先說(shuō)說(shuō)整體框架、思路,我打算結(jié)合兩部分分享給你,每一部分,相信仔細(xì)看完,都會(huì)或多或少有所收獲。以下內(nèi)容,預(yù)計(jì)1分鐘左右可快速看完:

                前一部分,方法篇,旨在詳細(xì)介紹DDD所包含的幾個(gè)核心概念,以及圍繞這些概念所構(gòu)建的DDD代碼實(shí)現(xiàn)模型的組成結(jié)構(gòu)。

                后半部分,實(shí)踐篇,進(jìn)一步思考。我繼續(xù)接著說(shuō),承接前面的內(nèi)容,要想讓這些代碼實(shí)現(xiàn)模型真正落地,我們需要把它們與具體的應(yīng)用場(chǎng)景結(jié)合起來(lái)。我將側(cè)重詳細(xì)闡述DDD代碼實(shí)現(xiàn)模型的設(shè)計(jì)方法,并給出一個(gè)具體的案例分析。

                伴隨著業(yè)務(wù)系統(tǒng)復(fù)雜度的不斷提升,以及微服務(wù)架構(gòu)等分布式技術(shù)體系的大行其道,領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain Driven Design,DDD),日漸成為系統(tǒng)建模領(lǐng)域的主流設(shè)計(jì)思想和模式。在DDD中,引入了限界上下文、聚合、實(shí)體、值對(duì)象、領(lǐng)域事件、資源庫(kù)、應(yīng)用服務(wù)等一系列核心概念。

                通過(guò)這些概念,開(kāi)發(fā)人員可以開(kāi)展系統(tǒng)設(shè)計(jì)和實(shí)現(xiàn)工作。但是,DDD中的這些概念相對(duì)都比較抽象,甚至有些晦澀難懂。再往相通或類(lèi)似問(wèn)題點(diǎn)上靠,我認(rèn)為實(shí)質(zhì)上對(duì)于復(fù)雜難懂的概念的理解和把握,我們一開(kāi)始不必過(guò)于糾結(jié)這些概念本身,而是可以把它們與現(xiàn)實(shí)中的具體實(shí)現(xiàn)模型對(duì)應(yīng)起來(lái)。

                通過(guò)兩者之間的合理映射,來(lái)促進(jìn)對(duì)概念本身的理解,如下圖所示。這里多說(shuō)一句,即便你是其他技術(shù)領(lǐng)域的朋友,或許也曾遇到過(guò)類(lèi)似問(wèn)題,并有著共通性。希望看完今天的分享,可以或多或少幫助到你,并有所啟發(fā)、思考。

                在上圖中,我們一方面嘗試把復(fù)雜概念映射到實(shí)現(xiàn)模型。另一方面,基于對(duì)實(shí)現(xiàn)模型的把握,可以反推對(duì)復(fù)雜概念的理解程度,從而更好地掌握這些概念。這也更足以見(jiàn)得實(shí)踐才能出真知,也只有設(shè)計(jì)過(guò)實(shí)現(xiàn)模型,才能真正掌握這些概念,從而把它們應(yīng)用到各種具體的場(chǎng)景中。

                這是一種行之有效的辦法。

                那么問(wèn)題就來(lái)了,在日常開(kāi)發(fā)過(guò)程中,如何確保DDD真正落地,把這些抽象概念轉(zhuǎn)為具體代碼模式,是我們今天要討論的內(nèi)容。

                01

                想設(shè)計(jì)代碼實(shí)現(xiàn)模型,咱非得了解DDD中這幾個(gè)核心概念?

                總體來(lái)說(shuō),DDD提供的是一種開(kāi)展業(yè)務(wù)建模和軟件設(shè)計(jì)的方法論。DDD認(rèn)為良好的系統(tǒng)架構(gòu),應(yīng)該是技術(shù)架構(gòu)和業(yè)務(wù)架構(gòu)相互融合的結(jié)果,開(kāi)發(fā)人員不能脫離業(yè)務(wù)領(lǐng)域來(lái)設(shè)計(jì)技術(shù)架構(gòu)。為了實(shí)現(xiàn)這一目標(biāo),DDD提出了一組核心概念,如圖1所示。

                我們先來(lái)看第一個(gè)核心概念,就比較難于理解,即限界上下文(Boundary Context)。在DDD中,當(dāng)我們把業(yè)務(wù)領(lǐng)域拆分成多個(gè)子域之后,限界上下文明確了子域的業(yè)務(wù)界限,并實(shí)現(xiàn)子域與子域之間的隔離,如圖2所示。

                有了限界上下文,我們就需要圍繞業(yè)務(wù)場(chǎng)景設(shè)計(jì)領(lǐng)域模型對(duì)象(Domain Model Object)。領(lǐng)域模型對(duì)象,包含了豐富的業(yè)務(wù)邏輯和操作行為,這點(diǎn)和只包含數(shù)據(jù)屬性的傳統(tǒng)數(shù)據(jù)對(duì)象,有本質(zhì)區(qū)別。

                因此,領(lǐng)域模型對(duì)象是我們?cè)趹?yīng)用DDD時(shí),最應(yīng)該關(guān)注的一組對(duì)象,也是最難把握的一組對(duì)象。

                在DDD中,領(lǐng)域模型對(duì)象包括三大類(lèi),即聚合(Aggregate)、實(shí)體(Entity)和值對(duì)象(Value Object),這三類(lèi)對(duì)象各有特點(diǎn)。

                相較領(lǐng)域模型對(duì)象,領(lǐng)域事件誕生較晚,但也是領(lǐng)域模型的一個(gè)重要組成部分,因?yàn)楝F(xiàn)實(shí)中很多場(chǎng)景,都可以抽象成事件(Event),如圖4。

                在DDD中,通過(guò)領(lǐng)域事件可以實(shí)現(xiàn)業(yè)務(wù)狀態(tài)變化的有效傳播,并在單個(gè)限界上下文內(nèi)部或在多個(gè)上下文之間,對(duì)這些狀態(tài)變化做出響應(yīng)。

                業(yè)務(wù)領(lǐng)域中的各種狀態(tài)變化最終都需要進(jìn)行存儲(chǔ)。為此,DDD提供了一個(gè)針對(duì)業(yè)務(wù)數(shù)據(jù)的統(tǒng)一訪問(wèn)入口,這就是資源庫(kù)(Repository)。通過(guò)資源庫(kù),我們可以實(shí)現(xiàn)對(duì)各種領(lǐng)域?qū)ο蟮某志没僮?,如圖5所示。

                最后,我們來(lái)引入應(yīng)用服務(wù)的概念。應(yīng)用服務(wù)包括命令(Command)服務(wù)和查詢(xún)(Query)服務(wù)兩大類(lèi),本質(zhì)上起到的是一種解耦和協(xié)調(diào)作用,確保各種領(lǐng)域模型對(duì)象之間的交互和協(xié)作。因此,在涉及到多個(gè)限界上下文之間的交互時(shí),我們需要重點(diǎn)關(guān)注應(yīng)用服務(wù)。如圖6所示。

                02

                概念復(fù)雜又難懂,想實(shí)際業(yè)務(wù)場(chǎng)景下真正落地,需引入DDD代碼實(shí)現(xiàn)模型

                關(guān)于DDD中的核心概念,我就簡(jiǎn)單介紹到這里,下一步就是要討論一個(gè)所有開(kāi)發(fā)人員都必須面對(duì)的話(huà)題,即如何將這些復(fù)雜難懂的概念,在現(xiàn)實(shí)的開(kāi)發(fā)過(guò)程中能夠真正落地?這就需要引入DDD代碼實(shí)現(xiàn)模型。

                要想設(shè)計(jì)代碼實(shí)現(xiàn)模型,先得搞清楚它有哪幾部分組成?

                無(wú)論設(shè)計(jì)方法有多好,能夠轉(zhuǎn)換為可運(yùn)行的代碼才是王道,這點(diǎn)對(duì)于DDD而言尤為如此。

                可惜的是,目前業(yè)界關(guān)于如何實(shí)施這些概念,并沒(méi)有一套統(tǒng)一的標(biāo)準(zhǔn)和規(guī)范,這就導(dǎo)致我們?cè)诰唧w的開(kāi)發(fā)過(guò)程中,常常感到無(wú)從下手。為此,本文專(zhuān)門(mén)提煉了一整套DDD代碼實(shí)現(xiàn)模型。接下來(lái),讓我們從DDD代碼實(shí)現(xiàn)模型的基本概念和組織結(jié)構(gòu)展開(kāi)討論。

                在講代碼實(shí)現(xiàn)模型之前,先弄清楚什么是實(shí)現(xiàn)模型

                說(shuō)起模型(Model),業(yè)界主流的方法論認(rèn)為存在三種不同的類(lèi)型,即領(lǐng)域模型、設(shè)計(jì)模型和代碼模型,如圖7所示。

                關(guān)于領(lǐng)域模型,我們?cè)谇懊娴膬?nèi)容中已經(jīng)做了介紹。在DDD中,聚合、實(shí)體、值對(duì)象、領(lǐng)域事件等,都可以歸屬到這一模型的范疇。

                而設(shè)計(jì)模型(Design Model),可以分成邊界模型和內(nèi)部模型兩個(gè)組成部分。邊界模型明確系統(tǒng)邊界,抽象系統(tǒng)集成和交互方案。而內(nèi)部模型細(xì)化邊界模型,在明確系統(tǒng)邊界的前提下,實(shí)現(xiàn)系統(tǒng)內(nèi)部模塊和組件的抽象和構(gòu)建。因此,在DDD中,我們往往從限界上下文的角度出發(fā),來(lái)開(kāi)展設(shè)計(jì)模型的建設(shè),如下圖所示。

                最后,代碼模型為現(xiàn)實(shí)世界的解決方案,提供可執(zhí)行的系統(tǒng)環(huán)境。我們可以通過(guò)在領(lǐng)域模型和設(shè)計(jì)模型中嵌入代碼的方式來(lái)構(gòu)建代碼模型,該模型是將DDD各個(gè)復(fù)雜概念轉(zhuǎn)換為可執(zhí)行代碼的關(guān)鍵所在,也是我們今天要討論的主要內(nèi)容。

                顯然,領(lǐng)域模型、設(shè)計(jì)模型和代碼模型之間,存在一種層次依賴(lài)關(guān)系,如圖9所示。

                首先,領(lǐng)域模型代表領(lǐng)域的固有業(yè)務(wù);

                設(shè)計(jì)模型指向領(lǐng)域模型,關(guān)注對(duì)外部接口的承諾以及交互關(guān)系;

                代碼模型提供了完整實(shí)現(xiàn)過(guò)程,是對(duì)設(shè)計(jì)模型的細(xì)化。

                正是通過(guò)這三種模型的整合,完成了從現(xiàn)實(shí)問(wèn)題到最終能夠落地的實(shí)現(xiàn)方案的演進(jìn)。

                DDD代碼實(shí)現(xiàn)模型,應(yīng)包含哪些部分?

                針對(duì)DDD代碼實(shí)現(xiàn)模型的討論,我們也將遵循上述三種模型的整合過(guò)程。結(jié)合DDD中的各種核心概念,我們梳理DDD代碼實(shí)現(xiàn)模型組成結(jié)構(gòu),如圖10所示。

                在上圖中,我們可以清晰看到DDD代碼實(shí)現(xiàn)模型的四個(gè)組成部分,分別面向領(lǐng)域?qū)ο蟆?yīng)用服務(wù)、基礎(chǔ)設(shè)施以及上下文集成。講到這里,你可能會(huì)問(wèn),為什么我們要這樣設(shè)計(jì)DDD的代碼實(shí)現(xiàn)模型呢?

                我們知道一個(gè)完整的DDD應(yīng)用程序,通常由多個(gè)限界上下文構(gòu)成。因此,對(duì)于代碼實(shí)現(xiàn)模型而言,我們需要重點(diǎn)考慮兩個(gè)維度,即:

                • 單個(gè)限界上下文實(shí)現(xiàn)過(guò)程中的代碼模型
                • 多個(gè)限界上下文之間集成過(guò)程中的代碼模型

                在上圖中,關(guān)于領(lǐng)域?qū)ο?、?yīng)用服務(wù)、基礎(chǔ)設(shè)施代碼實(shí)現(xiàn)模型的討論,屬于單個(gè)限界上下文的范疇,而上下文實(shí)現(xiàn)代碼集成模型,顯然面向多個(gè)限界上下文,如圖11所示。

                通過(guò)前面內(nèi)容的學(xué)習(xí),相信你對(duì)DDD代碼實(shí)現(xiàn)模型的組成結(jié)構(gòu),已了然在胸。

                那么,在日常開(kāi)發(fā)過(guò)程中,我們應(yīng)該如何設(shè)計(jì)這些代碼實(shí)現(xiàn)模型呢?有沒(méi)有具體的案例可以參考呢?這幾個(gè)問(wèn)題點(diǎn),你可以先停下來(lái)琢磨下。

                03 如何設(shè)計(jì)DDD代碼實(shí)現(xiàn)模型?

                在分析DDD代碼實(shí)現(xiàn)模型時(shí),對(duì)于上一篇提到的四個(gè)組成部分,我們需要梳理它們的代碼結(jié)構(gòu)和依賴(lài)關(guān)系。針對(duì)代碼結(jié)構(gòu),我們需要明確代碼包的組成,以及內(nèi)部所包含的技術(shù)組件。

                在明確了包結(jié)構(gòu)之后,依賴(lài)關(guān)系指的是我們需要進(jìn)一步明確這些代碼包和技術(shù)組件之間的交互關(guān)系。基于這兩點(diǎn),讓我們先來(lái)討論領(lǐng)域?qū)ο蟮拇a實(shí)現(xiàn)模型。

                領(lǐng)域?qū)ο蟠a實(shí)現(xiàn)模型

                針對(duì)領(lǐng)域?qū)ο?,我們通常用“domain”這個(gè)單詞,對(duì)代碼包結(jié)構(gòu)的頂層包進(jìn)行命名,在該包結(jié)構(gòu)下的所有技術(shù)組件,都屬于領(lǐng)域?qū)ο蟮姆懂牎?/p>

                具體而言,在DDD中,領(lǐng)域?qū)ο蟀I(lǐng)域模型對(duì)象、領(lǐng)域事件、資源庫(kù)以及應(yīng)用服務(wù)所涉及到的命令和查詢(xún)對(duì)象,其中領(lǐng)域模型對(duì)象可以分為聚合、實(shí)體和值對(duì)象這三大類(lèi)。

                因此,在DDD所有的代碼實(shí)現(xiàn)模型中,領(lǐng)域?qū)ο笊婕暗拇a結(jié)構(gòu)最為復(fù)雜,可以分成兩個(gè)層次,如圖1所示。

                圖1

                可以看到,這里的“domain”代表整個(gè)領(lǐng)域?qū)ο?,而“model”則代表領(lǐng)域模型對(duì)象,請(qǐng)注意這兩者在命名上的區(qū)別,以及它們之間的從屬關(guān)系。領(lǐng)域?qū)ο笫荄DD代碼實(shí)現(xiàn)模型的基礎(chǔ),包含核心業(yè)務(wù)邏輯的實(shí)現(xiàn)。

                應(yīng)用服務(wù)代碼實(shí)現(xiàn)模型

                類(lèi)似地,針對(duì)應(yīng)用服務(wù),我們通常使用“application”來(lái)命名頂層包結(jié)構(gòu)。應(yīng)用服務(wù)包含查詢(xún)服務(wù)和命令服務(wù)這兩大類(lèi),所以在子包的命名上,也會(huì)用“commandservice”和“queryservice”加以區(qū)分,如圖2所示。

                圖2

                顯然,命令服務(wù)和查詢(xún)服務(wù),分別依賴(lài)于領(lǐng)域?qū)ο蟠a實(shí)現(xiàn)模型中的命令對(duì)象和查詢(xún)對(duì)象,我們用虛線表示這層依賴(lài)關(guān)系。在DDD的代碼實(shí)現(xiàn)模型中,應(yīng)用服務(wù)可以說(shuō)是交互關(guān)系最為復(fù)雜的一個(gè)代碼模型。

                一方面,它需要將命令和查詢(xún)操作,分派給聚合對(duì)象等領(lǐng)域模型對(duì)象。

                另一方面,它也需要分別和基礎(chǔ)設(shè)施,以及其他限界上下文進(jìn)行交互。

                關(guān)于后者,我們?cè)谟懻摰桨咐治鰰r(shí),還會(huì)做進(jìn)一步展開(kāi)。

                基礎(chǔ)設(shè)施代碼實(shí)現(xiàn)模型

                其實(shí),所謂的基礎(chǔ)設(shè)施,指的是DDD應(yīng)用程序中所使用到的各種具體技術(shù)、工具和框架。常見(jiàn)的基礎(chǔ)設(shè)施類(lèi)組件主要包括這幾個(gè)方面:

                • 數(shù)據(jù)持久化(Persistence)
                • 消息通信(Messaging)
                • 系統(tǒng)配置(Config)
                • 安全控制(Security)

                因此,基礎(chǔ)設(shè)施的包結(jié)構(gòu)并不是固定的,而是根據(jù)具體的技術(shù)開(kāi)發(fā)要求進(jìn)行靈活的組織,這里給出一個(gè)常見(jiàn)的包結(jié)構(gòu),如圖3所示。針對(duì)基礎(chǔ)設(shè)施,我們使用了“infrastructure”,對(duì)這一包結(jié)構(gòu)進(jìn)行命名。

                圖3上圖中有一點(diǎn)需要注意,代表數(shù)據(jù)持久化的“persistence”包,和代表消息通信的“messaging”包,在基礎(chǔ)設(shè)施代碼實(shí)現(xiàn)模型中是最常見(jiàn)的,因?yàn)樗鼈兎謩e對(duì)應(yīng)著領(lǐng)域?qū)ο笾械馁Y源庫(kù)和領(lǐng)域事件。

                在DDD中,資源庫(kù)和領(lǐng)域事件的定義位于領(lǐng)域?qū)ο蟠a實(shí)現(xiàn)模型中,它們與具體的實(shí)現(xiàn)技術(shù)無(wú)關(guān)。而與具體實(shí)現(xiàn)技術(shù)相關(guān)的持久化和消息通信,則位于基礎(chǔ)設(shè)施代碼實(shí)現(xiàn)模型中。這里體現(xiàn)了領(lǐng)域?qū)ο笈c實(shí)現(xiàn)技術(shù)相互分離的設(shè)計(jì)原則。

                上下文集成代碼實(shí)現(xiàn)模型

                最后,我們來(lái)討論上下文集成代碼實(shí)現(xiàn)模型。需要注意的是,這個(gè)模型實(shí)現(xiàn)起來(lái)難度最大,因?yàn)樯婕暗蕉喾N系統(tǒng)集成技術(shù)體系。

                針對(duì)這一代碼實(shí)現(xiàn)模型,我們首先需要明確它是面向多個(gè)限界上下文的,所以我們需要考慮數(shù)據(jù)的流向,也就是所謂的內(nèi)向(Inbound)數(shù)據(jù)和外向(Outbound)數(shù)據(jù)。

                一方面,限界上下文,需要暴露訪問(wèn)入口供其他上下文進(jìn)行使用。站在當(dāng)前上下文角度看,這是一個(gè)Inbound操作。而當(dāng)某一個(gè)上下文向外部上下文發(fā)起請(qǐng)求時(shí),這就是一個(gè)Outbound操作,如圖4所示。

                圖4

                在代碼實(shí)現(xiàn)模型的設(shè)計(jì)上,我們也將采用“inbound”和“outbound”來(lái)命名包結(jié)構(gòu)。那么這兩個(gè)包結(jié)構(gòu)下,應(yīng)該包含哪些技術(shù)組件呢?

                我們先來(lái)討論“outbound”包結(jié)構(gòu),如圖5所示。 圖中,“rest”包中的REST API將外部請(qǐng)求,轉(zhuǎn)化為內(nèi)部的Command和Query對(duì)象,并交由應(yīng)用服務(wù)進(jìn)行處理。在這個(gè)轉(zhuǎn)化過(guò)程中,通常需要引入專(zhuān)門(mén)的DTO(Data Transfer Object,數(shù)據(jù)傳輸對(duì)象)對(duì)象,和組裝器(Assembler)對(duì)象。

                圖5

                同時(shí),“eventpublisher”包中的事件發(fā)布器(Event Publisher),則用來(lái)面向外部限界上下文發(fā)布領(lǐng)域事件。

                接著,我們討論“inbound”包結(jié)構(gòu)。在一個(gè)限界上下文中,數(shù)據(jù)的Inbound操作主要有兩類(lèi),一類(lèi)是防腐層(Anti-Corruption Layer,ACL),用來(lái)向遠(yuǎn)程REST API發(fā)起請(qǐng)求并獲取結(jié)果。另一類(lèi)是用來(lái)完成對(duì)領(lǐng)域事件進(jìn)行響應(yīng)的事件處理器(Event Handler),如圖6所示。

                圖6

                基于上下文集成過(guò)程,兩個(gè)上下文中的“inbound”和“outbound”包結(jié)構(gòu)中所包含的技術(shù)組件,實(shí)際上是一一對(duì)應(yīng)的,如圖7所示。

                可以看到,一個(gè)限界上下文“inbound”中的“acl”和“eventhandler”,分別對(duì)應(yīng)著另一個(gè)限界上下文“outbound”中的“rest”和“eventpublisher”。

                圖7

                至此,關(guān)于DDD中四大類(lèi)代碼實(shí)現(xiàn)模型,已介紹完。在接下來(lái)的內(nèi)容中,我們將基于一個(gè)具體的應(yīng)用場(chǎng)景,通過(guò)案例分析,將這些代碼實(shí)現(xiàn)模型付諸于實(shí)踐。基于這個(gè)案例,你可以將本文前面介紹的所有內(nèi)容,和日常開(kāi)發(fā)過(guò)程聯(lián)系起來(lái),進(jìn)一步掌握將模型轉(zhuǎn)化為具體代碼的實(shí)現(xiàn)方法和技巧。

                04 DDD代碼實(shí)現(xiàn)模型案例分析

                在現(xiàn)實(shí)世界中,工單處理是一個(gè)非常常見(jiàn)的業(yè)務(wù)需求。而工單的發(fā)起,通常都是因?yàn)橛脩?hù)需要對(duì)訂單進(jìn)行咨詢(xún)或投訴。

                在這個(gè)場(chǎng)景中,基于DDD的設(shè)計(jì)方法,我們可以分別拆分出工單(Ticket)、客服(Staff),以及訂單(Order)這三個(gè)限界上下文。在這三個(gè)上下文中,Ticket上下文,會(huì)分別與Staff和Order這兩個(gè)上下文進(jìn)行集成,從而創(chuàng)建工單申請(qǐng),如圖8所示。

                請(qǐng)注意,圖中展示了Ticket上下文,所具備的兩種不同的上下文集成方式。

                針對(duì)Staff上下文,Ticket上下文將使用REST API,完成對(duì)工單中客服數(shù)據(jù)的獲取。

                而針對(duì)Order上下文,則使用了領(lǐng)域事件,即一旦Order的狀態(tài)發(fā)生變化,Order上下文會(huì)發(fā)送對(duì)應(yīng)的領(lǐng)域事件到Ticket上下文中。

                圖8

                Ticket上下文代碼實(shí)現(xiàn)模型示例

                顯然,針對(duì)這一場(chǎng)景,Ticket上下文同時(shí)具備了Inbound和Outbound操作。因此,它的代碼實(shí)現(xiàn)模型是最完整的,如圖9所示。

                圖9

                上圖中,我們使用IDEA這款開(kāi)發(fā)工具和Spring Boot這一特定的開(kāi)發(fā)框架,構(gòu)建了Ticket限界上下文的代碼實(shí)現(xiàn)模型。我們可以很清晰地看到,DDD四種代碼實(shí)現(xiàn)模型的表現(xiàn)形式,就是五個(gè)頂層的代碼包結(jié)構(gòu)。其中,上下文集成代碼實(shí)現(xiàn)模型同時(shí)包含了“inbound”和“outbound”這兩個(gè)代碼包。

                我們?cè)賹?duì)這些頂層代碼包結(jié)構(gòu)做展開(kāi),可以得到如圖10所示的子代碼包結(jié)構(gòu)。

                圖10(上下滑動(dòng)查看)

                上圖所示的所有子代碼包結(jié)構(gòu),在前面的內(nèi)容中也都已經(jīng)給出了相應(yīng)的描述,這里便不再贅述。

                Ticket上下文中,命令服務(wù)TicketCommandService完成了對(duì)Staff服務(wù)的上下文集成,這時(shí)候采用的是防腐層ACL組件,示例代碼如下所示。

                可以看到,這里使用AclStaffService這個(gè)ACL組件,對(duì)Staff服務(wù)發(fā)起了遠(yuǎn)程調(diào)用,然后把返回結(jié)果填充到命令對(duì)象,并創(chuàng)建Ticket聚合。最終,我們通過(guò)TicketRepository完成了對(duì)聚合對(duì)象的持久化操作。

                圖11

                上述AclStaffService,就完成了對(duì)Staff上下文所提供的REST API的調(diào)用,示例代碼如下所示。這里用到了Spring自帶的RestTemplate模板工具類(lèi),完成對(duì)遠(yuǎn)程HTTP端點(diǎn)的訪問(wèn)操作。

                圖12

                Staff上下文代碼實(shí)現(xiàn)模型示例

                在Staff上下文,我們需要完成對(duì)上述REST API的構(gòu)建,它的代碼工程結(jié)構(gòu)如下圖所示。

                可以看到,相較Ticket上下文,Staff上下文的代碼結(jié)構(gòu)比較簡(jiǎn)單,因?yàn)樵撋舷挛闹恍枰峁?duì)外的“outbound”包,而基礎(chǔ)設(shè)施部分也只需要完成對(duì)領(lǐng)域?qū)ο蟮某志没僮骷纯伞?/p>

                圖13

                Order上下文代碼實(shí)現(xiàn)模型示例

                最后,我們來(lái)到Order限界上下文,它的代碼實(shí)現(xiàn)模型是這樣的,可以一同看下。

                圖14

                我們知道Order上下文,提供了針對(duì)Order數(shù)據(jù)的領(lǐng)域事件發(fā)布機(jī)制,所以它的“outbound”包中包含了用于發(fā)布領(lǐng)域事件的“eventpublisher”子包,并提供了一個(gè)OrderEventPublisherService,如下所示。

                圖15

                這里通過(guò)Spring Cloud Stream,實(shí)現(xiàn)了領(lǐng)域事件的發(fā)布。而在Ticket上下文中,我們同樣可以基于Spring Cloud Stream,實(shí)現(xiàn)對(duì)該領(lǐng)域事件的監(jiān)聽(tīng)和消費(fèi),示例代碼如下所示。

                圖16

                請(qǐng)注意,上述OrderUpdatedEventHandler,位于Ticket上下文“inbound”包的”eventhandler”子包中。

                關(guān)于這些具體實(shí)現(xiàn)代碼的講解不是本文的重點(diǎn),你可以參考筆者在Github上的案例代碼進(jìn)行系統(tǒng)學(xué)習(xí):https://github.com/tianminzheng/customer-service。

                05 總結(jié)和延伸思考

                今天的分享到這里就結(jié)束了。本文內(nèi)容詳細(xì)回答了開(kāi)發(fā)人員,在實(shí)現(xiàn)DDD應(yīng)用程序中所碰到的一個(gè)核心問(wèn)題,即如何構(gòu)建DDD的代碼實(shí)現(xiàn)模型。之所以要討論這個(gè)話(huà)題,原因在于DDD中的很多概念都比較晦澀難懂,而業(yè)界也沒(méi)有為如何實(shí)現(xiàn)這些概念,提供統(tǒng)一的開(kāi)發(fā)規(guī)范和標(biāo)準(zhǔn)。

                而通過(guò)將DDD中的各種復(fù)雜概念與具體代碼實(shí)現(xiàn)模型進(jìn)行映射,在幫我們更好地理解這些概念的同時(shí),也能夠?qū)⑺鼈冎苯討?yīng)用到日常開(kāi)發(fā)過(guò)程中。

                通過(guò)本文內(nèi)容的介紹,開(kāi)發(fā)人員可以結(jié)合自身的業(yè)務(wù)開(kāi)發(fā)需求,設(shè)計(jì)一套完整的DDD代碼實(shí)現(xiàn)模型。這里也附上全文思維導(dǎo)圖,助你回顧、梳理思路等。

                圖17 全文思維框架導(dǎo)圖-幫助你快速回顧、梳理、總結(jié)

                最后,我覺(jué)得還是有必要強(qiáng)調(diào)一點(diǎn)

                本文中給出的DDD代碼實(shí)現(xiàn)模型,也只是一個(gè)參考模型。而代碼實(shí)現(xiàn)模型的設(shè)計(jì),也與具體所采用的技術(shù)體系有一定關(guān)聯(lián)。在本文所展示的案例中,我們使用了Spring Boot、Spring Cloud Stream等Spring家族中的開(kāi)發(fā)框架,來(lái)開(kāi)發(fā)DDD應(yīng)用程序。

                而如果你使用Axon這種基于事件溯源模式的DDD開(kāi)發(fā)框架,那么在代碼實(shí)現(xiàn)模型中,就需要引入用于事件分發(fā)和存儲(chǔ)的Gateway、EventStore等組件,而位于基礎(chǔ)設(shè)施中的傳統(tǒng)數(shù)據(jù)持久化組件,可能就不一定會(huì)被使用到。

                當(dāng)然,基于我們今天介紹的內(nèi)容,相信你并不難對(duì)這套DDD代碼實(shí)現(xiàn)模型進(jìn)行擴(kuò)展。DDD作為一種系統(tǒng)建模方法論,也存在一些諸如分層架構(gòu)、整潔架構(gòu)、六邊形架構(gòu)等多種架構(gòu)風(fēng)格。

                針對(duì)每種架構(gòu)風(fēng)格,我們都需要設(shè)計(jì)對(duì)應(yīng)的代碼實(shí)現(xiàn)模型。

                而基于本文中介紹的內(nèi)容,通過(guò)對(duì)DDD中各個(gè)核心概念與實(shí)現(xiàn)模型之間進(jìn)行合理的映射,我在文中提供了一套設(shè)計(jì)代碼實(shí)現(xiàn)模型的系統(tǒng)方法,從而幫助你可以應(yīng)對(duì)不同架構(gòu)風(fēng)格的實(shí)現(xiàn)要求。

                這也是本文的核心價(jià)值所在。

                鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶(hù)投稿
                上一篇 2022年6月25日 15:42
                下一篇 2022年6月25日 15:42

                相關(guān)推薦

                • 事件營(yíng)銷(xiāo)案例

                  篇一成功營(yíng)銷(xiāo)案例小故事成功銷(xiāo)售案例小故事篇1模仿 一個(gè)人想做一套家具,就走到樹(shù)林里砍倒一棵樹(shù),并動(dòng)手把它鋸成木板這個(gè)人鋸樹(shù)的時(shí)候,把樹(shù)干的一頭擱在樹(shù)墩上,自己騎在樹(shù)干上還往鋸開(kāi)的縫…

                  2022年11月24日
                • 火影忍者所有忍術(shù)(火影忍者所有忍術(shù)讀法)

                  本文主要講的是火影忍者所有忍術(shù),以及和火影忍者所有忍術(shù)讀法相關(guān)的知識(shí),如果覺(jué)得本文對(duì)您有所幫助,不要忘了將本文分享給朋友。 火影忍者中所有忍術(shù)名稱(chēng)目錄? 1、萬(wàn)象天引——佩恩  2…

                  2022年11月24日
                • 園屬于什么結(jié)構(gòu)(園的結(jié)構(gòu)和部首)

                  園 yuán:全包圍結(jié)構(gòu),平穩(wěn)端正中稍帶左收右展。 外部“口” 體態(tài)端莊,稍抗肩,稍帶左輕右重。左豎起筆稍抖,豎身勿重,稍左斜,垂露收筆;第二筆橫折壓著左豎起筆,橫畫(huà)稍抗肩,不要重…

                  2022年11月24日
                • 中國(guó)未成年人保護(hù)發(fā)展首部藍(lán)皮書(shū)發(fā)布

                  記者從民政部獲悉,中國(guó)兒童福利和收養(yǎng)中心日前在京發(fā)布《中國(guó)未成年人保護(hù)發(fā)展報(bào)告藍(lán)皮書(shū)(2022)》,藍(lán)皮書(shū)填補(bǔ)了我國(guó)在未成年人保護(hù)發(fā)展領(lǐng)域系統(tǒng)研究的空白,是該領(lǐng)域首部藍(lán)皮書(shū)。 據(jù)介…

                  2022年11月23日
                • 自媒體哪個(gè)領(lǐng)域可以做到月入過(guò)萬(wàn)(現(xiàn)在自媒體哪個(gè)領(lǐng)域比較好做)

                  近年來(lái)自媒體行業(yè)非常火爆,不少人都紛紛加入,只需要一部手機(jī)電腦,隨時(shí)隨地都可以賺錢(qián),一些小伙伴甚至月入過(guò)萬(wàn),那么自媒體哪個(gè)領(lǐng)域可以做到月入過(guò)萬(wàn)?下面小編為大家?guī)?lái)自媒體可以做到月入…

                  2022年11月21日
                • 今年是冷冬還是暖冬?拉尼娜事件將持續(xù)至2022/2023年冬季

                  □ 拉尼娜事件是指赤道中、東太平洋的海水表面溫度低于正常年份溫度的現(xiàn)象,它與海面水溫持續(xù)高于常年溫度的厄爾尼諾事件相反,被認(rèn)為是可能導(dǎo)致全球氣候異常的重要信號(hào)。 □ 今年冬季影響我…

                  2022年11月21日
                • 馬斯克凌晨一點(diǎn)半曬“代碼審查”現(xiàn)場(chǎng),編排他的段子比瘋狂星期四還多

                  夢(mèng)晨 Pine 發(fā)自 凹非寺 量子位 | 公眾號(hào) QbitAI 每一個(gè)真正會(huì)寫(xiě)代碼的人,請(qǐng)?jiān)谙挛?點(diǎn)到總部10層報(bào)到。 每一個(gè)真正會(huì)寫(xiě)代碼的人,請(qǐng)?jiān)谙挛?點(diǎn)到總部10層報(bào)到。 馬斯…

                  2022年11月21日
                • 黑天鵝灰犀牛事件是什么意思(中國(guó)三次黑天鵝事件)

                  近些年來(lái),在一些新聞報(bào)刊或者文章里面,經(jīng)常提到“灰犀牛事件”。那這種說(shuō)法到底是什么意思呢? 所謂灰犀牛事件,是指概率極大、沖擊力極強(qiáng)的風(fēng)險(xiǎn),即可以預(yù)見(jiàn)很可能會(huì)發(fā)生,且影響十分巨大的…

                  2022年11月20日
                • 沒(méi)團(tuán)隊(duì)就做這幾種(一個(gè)人適合做哪一領(lǐng)域短視頻)

                  自媒體短視頻什么領(lǐng)域比較火呢?又有哪些領(lǐng)域收益高?現(xiàn)在自媒體短視頻越來(lái)越火了,很多新手想要入門(mén),但是又不知道做什么領(lǐng)域。經(jīng)過(guò)小編多方面觀察和統(tǒng)計(jì),發(fā)現(xiàn)了5個(gè)比較容易上熱門(mén)的視頻領(lǐng)域…

                  2022年11月19日
                • 自媒體怎么做做好這6點(diǎn),才算真正入了自媒體的門(mén)

                  自從自媒體火了以來(lái),有眾多的人涌進(jìn)了自媒體領(lǐng)域,雖然人數(shù)眾多,但是真正玩明白自媒體的,連20%都不到! 我算不算呢?我也不算,我只是一個(gè)正在學(xué)習(xí)的小學(xué)生! 也許我今天說(shuō)的話(huà),明天就…

                  2022年11月18日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息