一文帶你快速上手 DDD 領(lǐng)域驅(qū)動設(shè)計
DDD 讓人感覺晦澀難懂,主要是因為DDD誕生之初,是一個純粹的理論體系,它包含了各種復(fù)雜且難以理解的概念,它那一堆名詞與理論,讓人看起來很費力。
今天我們來直擊其本質(zhì),讓你快速上手DDD 領(lǐng)域驅(qū)動設(shè)計,let's go!
1、什么是 DDD
DDD(Domain-Driven Design,領(lǐng)域驅(qū)動設(shè)計)是一種軟件設(shè)計方法,專注于通過深入理解業(yè)務(wù)領(lǐng)域來構(gòu)建復(fù)雜的軟件系統(tǒng)。
DDD的核心思想是將業(yè)務(wù)需求與軟件設(shè)計緊密結(jié)合,通過建立清晰的領(lǐng)域模型,使開發(fā)人員和業(yè)務(wù)人員能夠以共同的語言交流,從而更好地解決業(yè)務(wù)問題。
簡單理解:DDD 不是架構(gòu),而是一種架構(gòu)設(shè)計方法論,它通過邊界劃分將復(fù)雜業(yè)務(wù)領(lǐng)域簡單化,幫我們設(shè)計出清晰的領(lǐng)域和應(yīng)用邊界,可以很容易地實現(xiàn)架構(gòu)演進(jìn)。
提到「架構(gòu)演進(jìn)」,我們就不得不提軟件架構(gòu)模式的演進(jìn)歷程。
2、軟件架構(gòu)模式的演進(jìn)
軟件架構(gòu)模式的演進(jìn)歷程是一個不斷適應(yīng)技術(shù)發(fā)展和業(yè)務(wù)需求變化的過程,主要經(jīng)歷以下三個階段:
- 單機(jī)架構(gòu):采用面向過程的設(shè)計方法,系統(tǒng)包括客戶端 UI 層和數(shù)據(jù)庫兩層,采用 C/S 架構(gòu)模式,整個系統(tǒng)圍繞數(shù)據(jù)庫驅(qū)動設(shè)計和開發(fā),并且總是從設(shè)計數(shù)據(jù)庫和字段開始。
- 集中式架構(gòu):采用面向?qū)ο蟮脑O(shè)計方法,系統(tǒng)包括業(yè)務(wù)接入層、業(yè)務(wù)邏輯層和數(shù)據(jù)庫層,采用經(jīng)典的三層架構(gòu),也有部分應(yīng)用采用傳統(tǒng)的 SOA 架構(gòu)。這種架構(gòu)容易使系統(tǒng)變得臃腫,可擴(kuò)展性和彈性伸縮性差。
當(dāng)然也有部分資料,將「集中式架構(gòu)」分解為垂直架構(gòu)/煙囪式架構(gòu) + 面向服務(wù)的架構(gòu)(SOA) 兩部分
- 分布式微服務(wù)架構(gòu):隨著微服務(wù)架構(gòu)理念的提出,集中式架構(gòu)正向分布式微服務(wù)架構(gòu)演進(jìn)。微服務(wù)架構(gòu)可以很好地實現(xiàn)應(yīng)用之間的解耦,解決單體應(yīng)用擴(kuò)展性和彈性伸縮能力不足的問題。
圖片
DDD 是一種架構(gòu)設(shè)計方法,微服務(wù)是一種架構(gòu)風(fēng)格。兩者都是為了拆解業(yè)務(wù)復(fù)雜度:合理劃分領(lǐng)域邊界,持續(xù)調(diào)整現(xiàn)有架構(gòu),優(yōu)化現(xiàn)有代碼,以保持架構(gòu)和代碼的生命力,也就是我們常說的演進(jìn)式架構(gòu)。
3、DDD 核心概念
DDD領(lǐng)域設(shè)計模型的核心概念:
- 領(lǐng)域(Domain):業(yè)務(wù)問題的范圍,是DDD領(lǐng)域設(shè)計模型的基礎(chǔ)。
- 限界上下文(Bounded Context):明確劃定的領(lǐng)域模型的邊界,它定義了領(lǐng)域內(nèi)詞匯表和模型的范圍,使得在同一限界上下文內(nèi)的開發(fā)人員能夠使用統(tǒng)一的語言進(jìn)行交流。
- 實體(Entity):領(lǐng)域中的核心概念,具有唯一標(biāo)識,并隨時間變化其屬性。實體在領(lǐng)域模型中通常表現(xiàn)為對象,具有業(yè)務(wù)邏輯和狀態(tài)。
- 值對象(Value Object):描述事物的對象,沒有唯一標(biāo)識,主要用于描述領(lǐng)域中的某個方面或?qū)傩?。值對象通常用于傳遞參數(shù)或?qū)嶓w進(jìn)行補充描述。
- 聚合(Aggregate):一組具有內(nèi)聚關(guān)系的相關(guān)對象的集合,用于確保數(shù)據(jù)一致性。聚合根是聚合中的核心實體,負(fù)責(zé)維護(hù)聚合內(nèi)部對象的一致性和完整性。
圖片
如何來劃定領(lǐng)域模型和微服務(wù)的邊界呢?
可以分三步來搞定~ (*^▽^*)
- 第一步:在事件風(fēng)暴中梳理業(yè)務(wù)過程中的用戶操作、事件以及外部依賴關(guān)系等,根據(jù)這些要素梳理出領(lǐng)域?qū)嶓w等領(lǐng)域?qū)ο蟆?/li>
- 第二步:根據(jù)領(lǐng)域?qū)嶓w之間的業(yè)務(wù)關(guān)聯(lián)性,將業(yè)務(wù)緊密相關(guān)的實體進(jìn)行組合形成聚合,同時確定聚合中的聚合根、值對象和實體。在上圖里,聚合之間的邊界是第一層邊界,它們在同一個微服務(wù)實例中運行,這個邊界是邏輯邊界,所以用虛線表示。
- 第三步:根據(jù)業(yè)務(wù)及語義邊界等因素,將一個或者多個聚合劃定在一個限界上下文內(nèi),形成領(lǐng)域模型。在上圖里,限界上下文之間的邊界是第二層邊界,這一層邊界可能就是未來微服務(wù)的邊界,不同限界上下文內(nèi)的領(lǐng)域邏輯被隔離在不同的微服務(wù)實例中運行,物理上相互隔離,所以是物理邊界,邊界之間用實線來表示。
4、DDD 架構(gòu)模型
三層架構(gòu)向 DDD 四層架構(gòu)演進(jìn),主要發(fā)生在業(yè)務(wù)邏輯層和數(shù)據(jù)訪問層。
圖片
DDD 四層架構(gòu)包含用戶接口層、應(yīng)用層、領(lǐng)域?qū)雍突A(chǔ)層。
通過這些層次劃分,我們可以明確微服務(wù)各層的職能,劃定各領(lǐng)域?qū)ο蟮倪吔?,確定各領(lǐng)域?qū)ο蟮膮f(xié)作方式:
- 接口層(接入層、表示層)
職責(zé):作為所有流量入口,負(fù)責(zé)接口定義和實現(xiàn),同時還包括消息的監(jiān)聽以及job的觸發(fā)入口。常見的接口類型包括grpc、http、mq、job等。
實踐:在Web應(yīng)用中,接口層通常包含Controller類,并按不同的客戶端(如移動端、管理端、開放接口等)進(jìn)行劃分。
- 應(yīng)用層
- 職責(zé):負(fù)責(zé)流程編排和差異化能力路由。它接收用戶請求,進(jìn)行必要的校驗和調(diào)度,然后轉(zhuǎn)發(fā)給領(lǐng)域?qū)犹幚?,并將處理結(jié)果返回給用戶。
- 實踐:應(yīng)用層通常包含服務(wù)編排類(如XxxAppService)、領(lǐng)域事件監(jiān)聽器(如XxxListener)、實體工廠(如XxxFactory)等。
- 領(lǐng)域?qū)?/li>
- 職責(zé):包含系統(tǒng)的核心業(yè)務(wù)邏輯和規(guī)則,是DDD架構(gòu)的核心。領(lǐng)域?qū)优c具體技術(shù)無關(guān),不依賴其他各層,確保了業(yè)務(wù)邏輯的獨立性和可復(fù)用性。
- 實踐:領(lǐng)域?qū)影搭I(lǐng)域聚合進(jìn)行劃分,外部聚合按限界上下文(微服務(wù))劃分。它定義了充血模型、值對象、倉庫接口、領(lǐng)域服務(wù)、領(lǐng)域事件等。領(lǐng)域契約(contract)包含API層特殊出入?yún)?、?shù)據(jù)查詢參數(shù)、領(lǐng)域事件等。
- 基礎(chǔ)層
- 職責(zé):與外部系統(tǒng)和資源交互,屏蔽外部特性,轉(zhuǎn)化成應(yīng)用內(nèi)識別定義的數(shù)據(jù)類型。它負(fù)責(zé)持久化機(jī)制實現(xiàn)、通用技術(shù)支持等。
- 實踐:基礎(chǔ)設(shè)施層包含倉庫層實現(xiàn)(如XxxRepositoryImpl)、外部服務(wù)實現(xiàn)(如封裝外部系統(tǒng)接口的引用,防止腐化領(lǐng)域模型)等。
5、DDD 應(yīng)用挑戰(zhàn)
雖然 DDD 領(lǐng)域設(shè)計模型具備一些應(yīng)用優(yōu)勢,但它畢竟不是銀彈,同樣存在一些應(yīng)用挑戰(zhàn)問題:
- 領(lǐng)域知識的獲?。航?zhǔn)確的領(lǐng)域模型需要深入的業(yè)務(wù)知識和對領(lǐng)域的深入理解。這可能需要與業(yè)務(wù)專家進(jìn)行大量的溝通和交流。
- 模型的復(fù)雜性:隨著業(yè)務(wù)領(lǐng)域的復(fù)雜性和規(guī)模的增加,領(lǐng)域模型可能會變得非常復(fù)雜和難以維護(hù)。
- 技術(shù)實現(xiàn)的挑戰(zhàn):DDD領(lǐng)域設(shè)計模型的具體實現(xiàn)需要考慮到具體的技術(shù)框架和平臺,這可能會增加開發(fā)的難度和復(fù)雜性。
6、總結(jié)
整篇梳理下來,我覺得DDD不像一門技術(shù),而更像是一種方法論,包含了很多設(shè)計理念。
知為行之始,行為知之成。準(zhǔn)確做事的前提是準(zhǔn)確的認(rèn)知。
DDD領(lǐng)域設(shè)計模型是一種非常有效的軟件設(shè)計方法,它可以幫助開發(fā)人員更好地理解業(yè)務(wù)領(lǐng)域,并開發(fā)出符合業(yè)務(wù)需求的軟件系統(tǒng)。然而,在實際應(yīng)用中,也需要考慮到領(lǐng)域知識的獲取、模型的復(fù)雜性和技術(shù)實現(xiàn)的挑戰(zhàn)等問題。