小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

領(lǐng)域驅(qū)動(dòng)實(shí)踐總結(jié)(基本理論總結(jié)與分析 架構(gòu)分析與代碼設(shè)計(jì)V 具體應(yīng)用設(shè)計(jì)分析)

 佬總圖書(shū)館 2022-07-01 發(fā)布于廣東

目錄

領(lǐng)域驅(qū)動(dòng)實(shí)踐總結(jié)二:架構(gòu)分析與代碼設(shè)計(jì)

一、微服務(wù)架構(gòu)模型的對(duì)比與選擇

(一)整潔架構(gòu)

(二)六邊形架構(gòu)

(三)DDD 分層架構(gòu)

1.用戶(hù)接口層

2.應(yīng)用層

3.領(lǐng)域?qū)?/a>

4.基礎(chǔ)層

5.從三層架構(gòu)向 DDD 分層架構(gòu)演進(jìn)

(四)三種微服務(wù)架構(gòu)模型的對(duì)比和分析

二、領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)分層架構(gòu)與微服務(wù)代碼模型

(一)代碼模型總目錄結(jié)構(gòu)

1.微服務(wù)一級(jí)目錄結(jié)構(gòu)

2.用戶(hù)接口層目錄結(jié)構(gòu)、職能和代碼形態(tài)

3.應(yīng)用層目錄結(jié)構(gòu)、職能和代碼形態(tài)

4.領(lǐng)域?qū)幽夸浗Y(jié)構(gòu)、職能和代碼形態(tài)

5.基礎(chǔ)層層目錄結(jié)構(gòu)、職能和代碼形態(tài)

(二)應(yīng)用層的領(lǐng)域?qū)ο蠓治?/a>

1.實(shí)體方法的封裝

2.領(lǐng)域服務(wù)的組合和封裝

3.應(yīng)用服務(wù)的組合和編排

(三)領(lǐng)域?qū)拥念I(lǐng)域?qū)ο蠓治?/a>

1.設(shè)計(jì)實(shí)體

2.找出聚合根

3.設(shè)計(jì)值對(duì)象

4.設(shè)計(jì)領(lǐng)域事件

5.設(shè)計(jì)領(lǐng)域服務(wù)

6.設(shè)計(jì)倉(cāng)儲(chǔ)

(四)代碼模型強(qiáng)調(diào)內(nèi)容

第一點(diǎn):聚合之間的代碼邊界一定要清晰。

第二點(diǎn):你一定要有代碼分層的概念。

三、正確理解微服務(wù)的邊界

(一)邏輯邊界

(二)物理邊界

(三)代碼邊界

四、正確認(rèn)識(shí)服務(wù)和數(shù)據(jù)在微服務(wù)各層的協(xié)作

(一)正確認(rèn)識(shí)服務(wù)的協(xié)作

1. 服務(wù)的類(lèi)型

2. 服務(wù)的調(diào)用(三類(lèi)主要場(chǎng)景)

微服務(wù)內(nèi)跨層服務(wù)調(diào)用

微服務(wù)之間的服務(wù)調(diào)用

領(lǐng)域事件驅(qū)動(dòng)

3. 服務(wù)的封裝與組合

(二)正確認(rèn)識(shí)服務(wù)數(shù)據(jù)的協(xié)作

1.基礎(chǔ)層數(shù)據(jù)協(xié)作

2.領(lǐng)域?qū)訑?shù)據(jù)協(xié)作

3.應(yīng)用層數(shù)據(jù)協(xié)作

4.用戶(hù)接口層數(shù)據(jù)協(xié)作

5.前端應(yīng)用數(shù)據(jù)協(xié)作

參考書(shū)籍、文獻(xiàn)和資料


領(lǐng)域驅(qū)動(dòng)實(shí)踐總結(jié)二:架構(gòu)分析與代碼設(shè)計(jì)

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)DDD是一種設(shè)計(jì)思想,它可以同時(shí)指導(dǎo)中臺(tái)業(yè)務(wù)建模和微服務(wù)設(shè)計(jì)(中臺(tái)本質(zhì)是業(yè)務(wù)模型,微服務(wù)是業(yè)務(wù)模型的系統(tǒng)落地),領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)強(qiáng)調(diào)領(lǐng)域模型和微服務(wù)設(shè)計(jì)的一體性,先有領(lǐng)域模型然后才有微服務(wù),而不是脫離領(lǐng)域模型來(lái)談微服務(wù)設(shè)計(jì)。

微服務(wù)拆分困境產(chǎn)生的根本原因:不知道業(yè)務(wù)或者微服務(wù)的邊界到底在什么地方。

DDD 核心思想:通過(guò)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)方法定義領(lǐng)域模型,從而確定業(yè)務(wù)和應(yīng)用邊界,保證業(yè)務(wù)模型與代碼模型的一致性。

對(duì)于領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的學(xué)習(xí)做的總結(jié)主要寫(xiě)三篇博客,主要包括三部分:基本理論總結(jié)與分析、架構(gòu)分析與代碼設(shè)計(jì)、具體應(yīng)用設(shè)計(jì)分析,主要參考的資料為極客時(shí)間的歐創(chuàng)新架構(gòu)師的《DDD》實(shí)戰(zhàn),其他參考書(shū)籍在文章下方的參考書(shū)籍中。

本次主要總結(jié)DDD架構(gòu)分析與代碼設(shè)計(jì):

一、微服務(wù)架構(gòu)模型的對(duì)比與選擇

微服務(wù)架構(gòu)模型現(xiàn)有的選擇模型包括:整潔架構(gòu)、CQRS 和六邊形架構(gòu)、DDD 分層架構(gòu)等。

(注:CQRS架構(gòu)之前博客中有講,本次不做分析)

每種架構(gòu)模式雖然提出的時(shí)代和背景不同,但其核心理念都是為了設(shè)計(jì)出“高內(nèi)聚低耦合”的架構(gòu),輕松實(shí)現(xiàn)架構(gòu)演進(jìn)。

DDD 分層架構(gòu)的思想使架構(gòu)邊界變得越來(lái)越清晰,它在微服務(wù)架構(gòu)模型中,占有非常重要的位置。建議選擇DDD 分層架構(gòu)。

(一)整潔架構(gòu)

在整潔架構(gòu)里,同心圓代表應(yīng)用軟件的不同部分,從里到外依次是領(lǐng)域模型、領(lǐng)域服務(wù)、應(yīng)用服務(wù)和最外圍的容易變化的內(nèi)容,比如用戶(hù)界面和基礎(chǔ)設(shè)施。

整潔架構(gòu)最主要的原則是依賴(lài)原則,它定義了各層的依賴(lài)關(guān)系,越往里依賴(lài)越低,代碼級(jí)別越高,越是核心能力。外圓代碼依賴(lài)只能指向內(nèi)圓,內(nèi)圓不需要知道外圓的任何情況。

(二)六邊形架構(gòu)

六邊形架構(gòu)的核心理念是:應(yīng)用是通過(guò)端口與外部進(jìn)行交互的。

也就是說(shuō),在下圖的六邊形架構(gòu)中,紅圈內(nèi)的核心業(yè)務(wù)邏輯(應(yīng)用程序和領(lǐng)域模型)與外部資源(包括 APP、Web 應(yīng)用以及數(shù)據(jù)庫(kù)資源等)完全隔離,僅通過(guò)適配器進(jìn)行交互。它解決了業(yè)務(wù)邏輯與用戶(hù)界面的代碼交錯(cuò)問(wèn)題,很好地實(shí)現(xiàn)了前后端分離。

六邊形架構(gòu)各層的依賴(lài)關(guān)系與整潔架構(gòu)一樣,都是由外向內(nèi)依賴(lài)。

六邊形架構(gòu)的一個(gè)端口可能對(duì)應(yīng)多個(gè)外部系統(tǒng),不同的外部系統(tǒng)也可能會(huì)使用不同的適配器,由適配器負(fù)責(zé)協(xié)議轉(zhuǎn)換。這就使得應(yīng)用程序能夠以一致的方式被用戶(hù)、程序、自動(dòng)化測(cè)試和批處理腳本使用。

(三)DDD 分層架構(gòu)

從上到下依次是:用戶(hù)接口層、應(yīng)用層、領(lǐng)域?qū)雍突A(chǔ)層。

1.用戶(hù)接口層

用戶(hù)接口層負(fù)責(zé)向用戶(hù)顯示信息和解釋用戶(hù)指令。

這里的用戶(hù)可能是:用戶(hù)、程序、自動(dòng)化測(cè)試和批處理腳本等等。

2.應(yīng)用層

應(yīng)用層是很薄的一層,理論上不應(yīng)該有業(yè)務(wù)規(guī)則或邏輯,主要面向用例和流程相關(guān)的操作。

位于領(lǐng)域?qū)又?,領(lǐng)域?qū)影鄠€(gè)聚合,所以它可以協(xié)調(diào)多個(gè)聚合的服務(wù)和領(lǐng)域?qū)ο笸瓿煞?wù)編排和組合,協(xié)作完成業(yè)務(wù)操作。

應(yīng)用層也是微服務(wù)之間交互的通道,它可以調(diào)用其它微服務(wù)的應(yīng)用服務(wù),完成微服務(wù)之間的服務(wù)組合和編排。

注意

  • 在設(shè)計(jì)和開(kāi)發(fā)時(shí),不要將本該放在領(lǐng)域?qū)拥臉I(yè)務(wù)邏輯放到應(yīng)用層中實(shí)現(xiàn)。因?yàn)辇嫶蟮膽?yīng)用層會(huì)使領(lǐng)域模型失焦,時(shí)間一長(zhǎng)你的微服務(wù)就會(huì)演化為傳統(tǒng)的三層架構(gòu),業(yè)務(wù)邏輯會(huì)變得混亂。
  • 應(yīng)用服務(wù)是在應(yīng)用層的,它負(fù)責(zé)服務(wù)的組合、編排和轉(zhuǎn)發(fā),負(fù)責(zé)處理業(yè)務(wù)用例的執(zhí)行順序以及結(jié)果的拼裝,以粗粒度的服務(wù)通過(guò) API 網(wǎng)關(guān)向前端發(fā)布。
  • 應(yīng)用服務(wù)還可以進(jìn)行安全認(rèn)證、權(quán)限校驗(yàn)、事務(wù)控制、發(fā)送或訂閱領(lǐng)域事件等。

3.領(lǐng)域?qū)?/h3>

領(lǐng)域?qū)拥淖饔檬?strong>實(shí)現(xiàn)企業(yè)核心業(yè)務(wù)邏輯,通過(guò)各種校驗(yàn)手段保證業(yè)務(wù)的正確性

領(lǐng)域?qū)?span>主要體現(xiàn)領(lǐng)域模型的業(yè)務(wù)能力,它用來(lái)表達(dá)業(yè)務(wù)概念、業(yè)務(wù)狀態(tài)和業(yè)務(wù)規(guī)則。

領(lǐng)域?qū)影?span>聚合根、實(shí)體、值對(duì)象、領(lǐng)域服務(wù)等領(lǐng)域模型中的領(lǐng)域?qū)ο蟆?/p>

注意:

  • 領(lǐng)域模型的業(yè)務(wù)邏輯主要是由實(shí)體和領(lǐng)域服務(wù)來(lái)實(shí)現(xiàn)的,其中實(shí)體會(huì)采用充血模型來(lái)實(shí)現(xiàn)所有與之相關(guān)的業(yè)務(wù)功能。
  • 實(shí)體和領(lǐng)域服務(wù)在實(shí)現(xiàn)業(yè)務(wù)邏輯上不是同級(jí)的,當(dāng)領(lǐng)域中的某些功能,單一實(shí)體(或者值對(duì)象)不能實(shí)現(xiàn)時(shí),領(lǐng)域服務(wù)就會(huì)出馬,它可以組合聚合內(nèi)的多個(gè)實(shí)體(或者值對(duì)象),實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)邏輯。

4.基礎(chǔ)層

基礎(chǔ)層是貫穿所有層的,它的作用就是為其它各層提供通用的技術(shù)和基礎(chǔ)服務(wù),包括第三方工具、驅(qū)動(dòng)、消息中間件、網(wǎng)關(guān)、文件、緩存以及數(shù)據(jù)庫(kù)等。比較常見(jiàn)的功能還是提供數(shù)據(jù)庫(kù)持久化。

基礎(chǔ)層包含基礎(chǔ)服務(wù),它采用依賴(lài)倒置設(shè)計(jì),封裝基礎(chǔ)資源服務(wù),實(shí)現(xiàn)應(yīng)用層、領(lǐng)域?qū)优c基礎(chǔ)層的解耦,降低外部資源變化對(duì)應(yīng)用的影響。

5.從三層架構(gòu)向 DDD 分層架構(gòu)演進(jìn)

DDD 分層架構(gòu)中的要素其實(shí)和三層架構(gòu)類(lèi)似,只是在 DDD 分層架構(gòu)中,這些要素被重新歸類(lèi),重新劃分了層,確定了層與層之間的交互規(guī)則和職責(zé)邊界。

  • 三層架構(gòu)向 DDD 分層架構(gòu)演進(jìn),主要發(fā)生在業(yè)務(wù)邏輯層和數(shù)據(jù)訪(fǎng)問(wèn)層。
  • DDD 分層架構(gòu)在用戶(hù)接口層引入了 DTO,給前端提供了更多的可使用數(shù)據(jù)和更高的展示靈活性。
  • DDD 分層架構(gòu)對(duì)三層架構(gòu)的業(yè)務(wù)邏輯層進(jìn)行了更清晰的劃分,改善了三層架構(gòu)核心業(yè)務(wù)邏輯混亂,代碼改動(dòng)相互影響大的情況。
  • DDD 分層架構(gòu)將業(yè)務(wù)邏輯層的服務(wù)拆分到了應(yīng)用層和領(lǐng)域?qū)?/span>。應(yīng)用層快速響應(yīng)前端的變化,領(lǐng)域?qū)訉?shí)現(xiàn)領(lǐng)域模型的能力。
  • 數(shù)據(jù)訪(fǎng)問(wèn)層和基礎(chǔ)層之間三層架構(gòu)數(shù)據(jù)訪(fǎng)問(wèn)采用 DAO 方式;DDD 分層架構(gòu)的數(shù)據(jù)庫(kù)等基礎(chǔ)資源訪(fǎng)問(wèn),采用了倉(cāng)儲(chǔ)(Repository)設(shè)計(jì)模式,通過(guò)依賴(lài)倒置實(shí)現(xiàn)各層對(duì)基礎(chǔ)資源的解耦。倉(cāng)儲(chǔ)又分為兩部分:倉(cāng)儲(chǔ)接口和倉(cāng)儲(chǔ)實(shí)現(xiàn)。倉(cāng)儲(chǔ)接口放在領(lǐng)域?qū)?/span>中,倉(cāng)儲(chǔ)實(shí)現(xiàn)放在基礎(chǔ)層。原來(lái)三層架構(gòu)通用的第三方工具包、驅(qū)動(dòng)、Common、Utility、Config 等通用的公共的資源類(lèi)統(tǒng)一放到了基礎(chǔ)層。

(四)三種微服務(wù)架構(gòu)模型的對(duì)比和分析

  • 重點(diǎn)關(guān)注圖中的紅色線(xiàn)框,它們是非常重要的分界線(xiàn),這三種架構(gòu)里面都有,它的作用就是將核心業(yè)務(wù)邏輯與外部應(yīng)用、基礎(chǔ)資源進(jìn)行隔離。
  • 紅色框內(nèi)部主要實(shí)現(xiàn)核心業(yè)務(wù)邏輯,劃分了應(yīng)用層和領(lǐng)域?qū)?/span>,來(lái)承擔(dān)不同的業(yè)務(wù)邏輯。
  • 領(lǐng)域?qū)訉?shí)現(xiàn)面向領(lǐng)域模型,實(shí)現(xiàn)領(lǐng)域模型的核心業(yè)務(wù)邏輯,屬于原子模型,它需要保持領(lǐng)域模型和業(yè)務(wù)邏輯的穩(wěn)定,對(duì)外提供穩(wěn)定的細(xì)粒度的領(lǐng)域服務(wù),所以它處于架構(gòu)的核心位置。
  • 應(yīng)用層實(shí)現(xiàn)面向用戶(hù)操作相關(guān)的用例和流程,對(duì)外提供粗粒度的 API 服務(wù)。它就像一個(gè)齒輪一樣進(jìn)行前臺(tái)應(yīng)用和領(lǐng)域?qū)拥倪m配,接收前臺(tái)需求,隨時(shí)做出響應(yīng)和調(diào)整,盡量避免將前臺(tái)需求傳導(dǎo)到領(lǐng)域?qū)印?span>應(yīng)用層作為配速齒輪則位于前臺(tái)應(yīng)用和領(lǐng)域?qū)又g。

二、領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)分層架構(gòu)與微服務(wù)代碼模型

DDD 并沒(méi)有給出標(biāo)準(zhǔn)的代碼模型,不同的人可能會(huì)有不同理解。這里我們?cè)谑褂玫臅r(shí)候還是建議按照歐創(chuàng)新架構(gòu)師總結(jié)的來(lái)進(jìn)行適用,具體如下:

(一)代碼模型總目錄結(jié)構(gòu)

根據(jù) DDD 分層架構(gòu)模型建立了標(biāo)準(zhǔn)的微服務(wù)代碼模型,在代碼模型里面,各代碼對(duì)象各據(jù)其位、各司其職,共同協(xié)作完成微服務(wù)的業(yè)務(wù)邏輯。它包括用戶(hù)接口層、應(yīng)用層、領(lǐng)域?qū)雍突A(chǔ)層,分層架構(gòu)各層的職責(zé)邊界非常清晰,又能有條不紊地分層協(xié)作。

  • 用戶(hù)接口層:面向前端提供服務(wù)適配,面向資源層提供資源適配。這一層聚集了接口適配相關(guān)的功能。
  • 應(yīng)用層職責(zé):實(shí)現(xiàn)服務(wù)組合和編排,適應(yīng)業(yè)務(wù)流程快速變化的需求。這一層聚集了應(yīng)用服務(wù)和事件相關(guān)的功能。
  • 領(lǐng)域?qū)樱簩?shí)現(xiàn)領(lǐng)域的核心業(yè)務(wù)邏輯。這一層聚集了領(lǐng)域模型的聚合、聚合根、實(shí)體、值對(duì)象、領(lǐng)域服務(wù)和事件等領(lǐng)域?qū)ο?,以及它們組合所形成的業(yè)務(wù)能力。
  • 基礎(chǔ)層:貫穿所有層,為各層提供基礎(chǔ)資源服務(wù)。這一層聚集了各種底層資源相關(guān)的服務(wù)和能力。

業(yè)務(wù)邏輯從領(lǐng)域?qū)?、?yīng)用層到用戶(hù)接口層逐層封裝和協(xié)作,對(duì)外提供靈活的服務(wù),既實(shí)現(xiàn)了各層的分工,又實(shí)現(xiàn)了各層的協(xié)作。

1.微服務(wù)一級(jí)目錄結(jié)構(gòu)

微服務(wù)一級(jí)目錄是按照 DDD 分層架構(gòu)的分層職責(zé)來(lái)定義的。從下面這張圖中,我們可以看到,在代碼模型里分別為用戶(hù)接口層、應(yīng)用層、領(lǐng)域?qū)雍突A(chǔ)層,建立了 interfaces、application、domain 和 infrastructure 四個(gè)一級(jí)代碼目錄。

2.用戶(hù)接口層目錄結(jié)構(gòu)、職能和代碼形態(tài)

主要存放用戶(hù)接口層與前端交互、展現(xiàn)數(shù)據(jù)相關(guān)的代碼。前端應(yīng)用通過(guò)這一層的接口,向應(yīng)用服務(wù)獲取展現(xiàn)所需的數(shù)據(jù)。這一層主要用來(lái)處理用戶(hù)發(fā)送的 Restful 請(qǐng)求,解析用戶(hù)輸入的配置文件,并將數(shù)據(jù)傳遞給 Application 層。數(shù)據(jù)的組裝、數(shù)據(jù)傳輸格式以及 Facade 接口等代碼都會(huì)放在這一層目錄里。

具體如下:

  • Assembler:實(shí)現(xiàn) DTO 與領(lǐng)域?qū)ο笾g的相互轉(zhuǎn)換和數(shù)據(jù)交換。一般來(lái)說(shuō) Assembler 與 DTO 總是一同出現(xiàn)。
  • Dto:它是數(shù)據(jù)傳輸?shù)妮d體,內(nèi)部不存在任何業(yè)務(wù)邏輯,我們可以通過(guò) DTO 把內(nèi)部的領(lǐng)域?qū)ο笈c外界隔離。
  • Facade:提供較粗粒度的調(diào)用接口,將用戶(hù)請(qǐng)求委派給一個(gè)或多個(gè)應(yīng)用服務(wù)進(jìn)行處理。

3.應(yīng)用層目錄結(jié)構(gòu)、職能和代碼形態(tài)

主要存放應(yīng)用層服務(wù)組合和編排相關(guān)的代碼。應(yīng)用服務(wù)向下基于微服務(wù)內(nèi)的領(lǐng)域服務(wù)或外部微服務(wù)的應(yīng)用服務(wù)完成服務(wù)的編排和組合,向上為用戶(hù)接口層提供各種應(yīng)用數(shù)據(jù)展現(xiàn)支持服務(wù)。應(yīng)用服務(wù)和事件等代碼會(huì)放在這一層目錄里。

具體如下:

  • Event(事件):這層目錄主要存放事件相關(guān)的代碼。它包括兩個(gè)子目錄:publish 和 subscribe。前者主要存放事件發(fā)布相關(guān)代碼,后者主要存放事件訂閱相關(guān)代碼(事件處理相關(guān)的核心業(yè)務(wù)邏輯在領(lǐng)域?qū)訉?shí)現(xiàn))。為了實(shí)現(xiàn)事件的統(tǒng)一管理,建議你將微服務(wù)內(nèi)所有事件的發(fā)布和訂閱的處理都統(tǒng)一放到應(yīng)用層,事件相關(guān)的核心業(yè)務(wù)邏輯實(shí)現(xiàn)放在領(lǐng)域?qū)?/span>。通過(guò)應(yīng)用層調(diào)用領(lǐng)域?qū)臃?wù),來(lái)實(shí)現(xiàn)完整的事件發(fā)布和訂閱處理流程。
  • Service(應(yīng)用服務(wù)):這層的服務(wù)是應(yīng)用服務(wù)。應(yīng)用服務(wù)會(huì)對(duì)多個(gè)領(lǐng)域服務(wù)或外部應(yīng)用服務(wù)進(jìn)行封裝、編排和組合,對(duì)外提供粗粒度的服務(wù)。應(yīng)用服務(wù)主要實(shí)現(xiàn)服務(wù)組合和編排,是一段獨(dú)立的業(yè)務(wù)邏輯。你可以將所有應(yīng)用服務(wù)放在一個(gè)應(yīng)用服務(wù)類(lèi)里,也可以把一個(gè)應(yīng)用服務(wù)設(shè)計(jì)為一個(gè)應(yīng)用服務(wù)類(lèi),以防應(yīng)用服務(wù)類(lèi)代碼量過(guò)大。

4.領(lǐng)域?qū)幽夸浗Y(jié)構(gòu)、職能和代碼形態(tài)

主要存放領(lǐng)域?qū)雍诵臉I(yè)務(wù)邏輯相關(guān)的代碼。領(lǐng)域?qū)涌梢园?span>多個(gè)聚合代碼包,它們共同實(shí)現(xiàn)領(lǐng)域模型的核心業(yè)務(wù)邏輯。聚合以及聚合內(nèi)的實(shí)體、方法、領(lǐng)域服務(wù)和事件等代碼會(huì)放在這一層目錄里。

具體如下:

  • Aggregate(聚合):它是聚合軟件包的根目錄,可以根據(jù)實(shí)際項(xiàng)目的聚合名稱(chēng)命名,比如權(quán)限聚合。在聚合內(nèi)定義聚合根、實(shí)體和值對(duì)象以及領(lǐng)域服務(wù)之間的關(guān)系和邊界。聚合內(nèi)實(shí)現(xiàn)高內(nèi)聚的業(yè)務(wù)邏輯,它的代碼可以獨(dú)立拆分為微服務(wù)。以聚合為單位的代碼放在一個(gè)包里的主要目的是為了業(yè)務(wù)內(nèi)聚,而更大的目的是為了以后微服務(wù)之間聚合的重組。聚合之間清晰的代碼邊界,可以讓你輕松地實(shí)現(xiàn)以聚合為單位的微服務(wù)重組,在微服務(wù)架構(gòu)演進(jìn)中有著很重要的作用。
  • Entity(實(shí)體):它存放聚合根、實(shí)體、值對(duì)象以及工廠(chǎng)模式(Factory)相關(guān)代碼。實(shí)體類(lèi)采用充血模型,同一實(shí)體相關(guān)的業(yè)務(wù)邏輯都在實(shí)體類(lèi)代碼中實(shí)現(xiàn)。跨實(shí)體的業(yè)務(wù)邏輯代碼在領(lǐng)域服務(wù)中實(shí)現(xiàn)。
  • Event(事件):它存放事件實(shí)體以及與事件活動(dòng)相關(guān)的業(yè)務(wù)邏輯代碼。
  • Service(領(lǐng)域服務(wù)):它存放領(lǐng)域服務(wù)代碼一個(gè)領(lǐng)域服務(wù)是多個(gè)實(shí)體組合出來(lái)的一段業(yè)務(wù)邏輯。你可以將聚合內(nèi)所有領(lǐng)域服務(wù)都放在一個(gè)領(lǐng)域服務(wù)類(lèi)中,你也可以把每一個(gè)領(lǐng)域服務(wù)設(shè)計(jì)為一個(gè)類(lèi)。如果領(lǐng)域服務(wù)內(nèi)的業(yè)務(wù)邏輯相對(duì)復(fù)雜,建議將一個(gè)領(lǐng)域服務(wù)設(shè)計(jì)為一個(gè)領(lǐng)域服務(wù)類(lèi),避免由于所有領(lǐng)域服務(wù)代碼都放在一個(gè)領(lǐng)域服務(wù)類(lèi)中,而出現(xiàn)代碼臃腫的問(wèn)題。領(lǐng)域服務(wù)封裝多個(gè)實(shí)體或方法后向上層提供應(yīng)用服務(wù)調(diào)用。
  • Repository(倉(cāng)儲(chǔ)):它存放所在聚合的查詢(xún)或持久化領(lǐng)域?qū)ο蟮拇a,通常包括倉(cāng)儲(chǔ)接口和倉(cāng)儲(chǔ)實(shí)現(xiàn)方法。為了方便聚合的拆分和組合,我們?cè)O(shè)定了一個(gè)原則:一個(gè)聚合對(duì)應(yīng)一個(gè)倉(cāng)儲(chǔ)。(特別說(shuō)明:按照 DDD 分層架構(gòu),倉(cāng)儲(chǔ)實(shí)現(xiàn)本應(yīng)該屬于基礎(chǔ)層代碼,但為了在微服務(wù)架構(gòu)演進(jìn)時(shí),保證代碼拆分和重組的便利性,把聚合倉(cāng)儲(chǔ)實(shí)現(xiàn)的代碼放到了聚合包內(nèi)。)

5.基礎(chǔ)層層目錄結(jié)構(gòu)、職能和代碼形態(tài)

主要存放基礎(chǔ)資源服務(wù)相關(guān)的代碼,為其它各層提供的通用技術(shù)能力、三方軟件包、數(shù)據(jù)庫(kù)服務(wù)、配置和基礎(chǔ)資源服務(wù)的代碼都會(huì)放在這一層目錄里。

具體如下:

  • Config:主要存放配置相關(guān)代碼。
  • Util:主要存放平臺(tái)、開(kāi)發(fā)框架、消息、數(shù)據(jù)庫(kù)、緩存、文件、總線(xiàn)、網(wǎng)關(guān)、第三方類(lèi)庫(kù)、通用算法等基礎(chǔ)代碼,你可以為不同的資源類(lèi)別建立不同的子目錄。

(二)應(yīng)用層的領(lǐng)域?qū)ο蠓治?/h2>

應(yīng)用層的主要領(lǐng)域?qū)ο笫菓?yīng)用服務(wù)和事件的發(fā)布以及訂閱。

在事件風(fēng)暴或領(lǐng)域故事分析時(shí),我們往往會(huì)根據(jù)用戶(hù)或系統(tǒng)發(fā)起的命令,來(lái)設(shè)計(jì)服務(wù)或?qū)嶓w方法。為了響應(yīng)這個(gè)命令,我們需要分析和記錄:

  • 在應(yīng)用層和領(lǐng)域?qū)臃謩e會(huì)發(fā)生哪些業(yè)務(wù)行為;
  • 各層分別需要設(shè)計(jì)哪些服務(wù)或者方法;
  • 這些方法和服務(wù)的分層以及領(lǐng)域類(lèi)型(比如實(shí)體方法、領(lǐng)域服務(wù)和應(yīng)用服務(wù)等),它們之間的調(diào)用和組合的依賴(lài)關(guān)系。

在嚴(yán)格分層架構(gòu)模式下,不允許服務(wù)的跨層調(diào)用,每個(gè)服務(wù)只能調(diào)用它的下一層服務(wù)。服務(wù)從下到上依次為:實(shí)體方法、領(lǐng)域服務(wù)和應(yīng)用服務(wù)。建議采用服務(wù)逐層封裝的方式,服務(wù)的封裝和調(diào)用主要有以下幾種方式:

1.實(shí)體方法的封裝

實(shí)體方法是最底層的原子業(yè)務(wù)邏輯。

  • 如果單一實(shí)體的方法需要被跨層調(diào)用,你可以將它封裝成領(lǐng)域服務(wù),這樣封裝的領(lǐng)域服務(wù)就可以被應(yīng)用服務(wù)調(diào)用和編排了。
  • 如果它還需要被用戶(hù)接口層調(diào)用,需要將這個(gè)領(lǐng)域服務(wù)封裝成應(yīng)用服務(wù)。

經(jīng)過(guò)逐層服務(wù)封裝,實(shí)體方法就可以暴露給上面不同的層,實(shí)現(xiàn)跨層調(diào)用。

封裝時(shí)服務(wù)前面的名字可以保持一致,你可以用 *DomainService 或 *AppService 后綴來(lái)區(qū)分領(lǐng)域服務(wù)或應(yīng)用服務(wù)

2.領(lǐng)域服務(wù)的組合和封裝

領(lǐng)域服務(wù)會(huì)對(duì)多個(gè)實(shí)體和實(shí)體方法進(jìn)行組合和編排,供應(yīng)用服務(wù)調(diào)用。

如果它需要暴露給用戶(hù)接口層,領(lǐng)域服務(wù)就需要封裝成應(yīng)用服務(wù)。

3.應(yīng)用服務(wù)的組合和編排

應(yīng)用服務(wù)會(huì)對(duì)多個(gè)領(lǐng)域服務(wù)進(jìn)行組合和編排,暴露給用戶(hù)接口層,供前端應(yīng)用調(diào)用。

多個(gè)應(yīng)用服務(wù)可能會(huì)對(duì)多個(gè)同樣的領(lǐng)域服務(wù)重復(fù)進(jìn)行同樣業(yè)務(wù)邏輯的組合和編排。當(dāng)出現(xiàn)這種情況時(shí),就需要分析是不是領(lǐng)域服務(wù)可以整合了??梢詫⑦@幾個(gè)不斷重復(fù)組合的領(lǐng)域服務(wù),合并到一個(gè)領(lǐng)域服務(wù)中實(shí)現(xiàn),這樣領(lǐng)域模型將會(huì)越來(lái)越精煉,更能適應(yīng)業(yè)務(wù)的要求。

應(yīng)用服務(wù)類(lèi)放在應(yīng)用層 Service 目錄結(jié)構(gòu)下。領(lǐng)域事件的發(fā)布和訂閱類(lèi)放在應(yīng)用層 Event 目錄結(jié)構(gòu)下。

(三)領(lǐng)域?qū)拥念I(lǐng)域?qū)ο蠓治?/h2>

事件風(fēng)暴結(jié)束時(shí),領(lǐng)域模型聚合內(nèi)一般會(huì)有:聚合、實(shí)體、命令和領(lǐng)域事件等領(lǐng)域?qū)ο?/span>。

在完成故事分析和微服務(wù)設(shè)計(jì)后,微服務(wù)的聚合內(nèi)一般會(huì)有:聚合、聚合根、實(shí)體、值對(duì)象、領(lǐng)域事件、領(lǐng)域服務(wù)和倉(cāng)儲(chǔ)等領(lǐng)域?qū)ο蟆?/span>

1.設(shè)計(jì)實(shí)體

大多數(shù)情況下,領(lǐng)域模型的業(yè)務(wù)實(shí)體與微服務(wù)的數(shù)據(jù)庫(kù)實(shí)體是一一對(duì)應(yīng)的。

但某些領(lǐng)域模型的實(shí)體在微服務(wù)設(shè)計(jì)時(shí),可能會(huì)被設(shè)計(jì)為多個(gè)數(shù)據(jù)實(shí)體,或者實(shí)體的某些屬性被設(shè)計(jì)為值對(duì)象。

在分層架構(gòu)里,實(shí)體采用充血模型,在實(shí)體類(lèi)內(nèi)實(shí)現(xiàn)實(shí)體的全部業(yè)務(wù)邏輯。這些不同的實(shí)體都有自己的方法和業(yè)務(wù)行為,比如地址實(shí)體有新增和修改地址的方法,銀行賬號(hào)實(shí)體有新增和修改銀行賬號(hào)的方法。

實(shí)體類(lèi)放在領(lǐng)域?qū)拥?Entity 目錄結(jié)構(gòu)下。

2.找出聚合根

聚合根來(lái)源于領(lǐng)域模型,聚合根是一種特殊的實(shí)體,它有自己的屬性和方法。聚合根可以實(shí)現(xiàn)聚合之間的對(duì)象引用,還可以引用聚合內(nèi)的所有實(shí)體。

  • 在個(gè)人客戶(hù)聚合里,個(gè)人客戶(hù)這個(gè)實(shí)體是聚合根,它負(fù)責(zé)管理地址、電話(huà)以及銀行賬號(hào)的生命周期。
  • 個(gè)人客戶(hù)聚合根通過(guò)工廠(chǎng)和倉(cāng)儲(chǔ)模式,實(shí)現(xiàn)聚合內(nèi)陸址、銀行賬號(hào)等實(shí)體和值對(duì)象數(shù)據(jù)的初始化和持久化。

聚合根類(lèi)放在代碼模型的 Entity 目錄結(jié)構(gòu)下。聚合根有自己的實(shí)現(xiàn)方法,比如生成客戶(hù)編碼,新增和修改客戶(hù)信息等方法。

3.設(shè)計(jì)值對(duì)象

根據(jù)需要將某些實(shí)體的某些屬性或?qū)傩约O(shè)計(jì)為值對(duì)象。值對(duì)象類(lèi)放在代碼模型的 Entity 目錄結(jié)構(gòu)下。

在個(gè)人客戶(hù)聚合中,客戶(hù)擁有客戶(hù)證件類(lèi)型,它是以枚舉值的形式存在,所以將它設(shè)計(jì)為值對(duì)象。

有些領(lǐng)域?qū)ο罂梢栽O(shè)計(jì)為值對(duì)象,也可以設(shè)計(jì)為實(shí)體,我們需要根據(jù)具體情況來(lái)分析:

  • 如果這個(gè)領(lǐng)域?qū)ο笤谄渌酆蟽?nèi)維護(hù)生命周期,且在它依附的實(shí)體對(duì)象中只允許整體替換,我們就可以將它設(shè)計(jì)為值對(duì)象。
  • 如果這個(gè)對(duì)象是多條且需要基于它做查詢(xún)統(tǒng)計(jì),建議將它設(shè)計(jì)為實(shí)體。

4.設(shè)計(jì)領(lǐng)域事件

如果領(lǐng)域模型中領(lǐng)域事件會(huì)觸發(fā)下一步的業(yè)務(wù)操作,我們就需要設(shè)計(jì)領(lǐng)域事件。

  • 首先確定領(lǐng)域事件發(fā)生在微服務(wù)內(nèi)還是微服務(wù)之間。
  • 然后設(shè)計(jì)事件實(shí)體對(duì)象,事件的發(fā)布和訂閱機(jī)制,以及事件的處理機(jī)制。
  • 判斷是否需要引入事件總線(xiàn)或消息中間件

領(lǐng)域事件實(shí)體和處理類(lèi)放在領(lǐng)域?qū)拥?Event 目錄結(jié)構(gòu)下。領(lǐng)域事件的發(fā)布和訂閱類(lèi)建議放在應(yīng)用層的 Event 目錄結(jié)構(gòu)下。

5.設(shè)計(jì)領(lǐng)域服務(wù)

如果一個(gè)業(yè)務(wù)動(dòng)作或行為跨多個(gè)實(shí)體,我們就需要設(shè)計(jì)領(lǐng)域服務(wù)。

領(lǐng)域服務(wù)通過(guò)對(duì)多個(gè)實(shí)體和實(shí)體方法進(jìn)行組合,完成核心業(yè)務(wù)邏輯??梢哉J(rèn)為領(lǐng)域服務(wù)是位于實(shí)體方法之上和應(yīng)用服務(wù)之下的一層業(yè)務(wù)邏輯。

按照嚴(yán)格分層架構(gòu)層的依賴(lài)關(guān)系

  • 如果實(shí)體的方法需要暴露給應(yīng)用層,它需要封裝成領(lǐng)域服務(wù)后才可以被應(yīng)用服務(wù)調(diào)用。
  • 如果有的實(shí)體方法需要被前端應(yīng)用調(diào)用,我們會(huì)將它封裝成領(lǐng)域服務(wù),然后再封裝為應(yīng)用服務(wù)。

領(lǐng)域服務(wù)類(lèi)放在領(lǐng)域?qū)拥?Service 目錄結(jié)構(gòu)下。

6.設(shè)計(jì)倉(cāng)儲(chǔ)

每一個(gè)聚合都有一個(gè)倉(cāng)儲(chǔ),倉(cāng)儲(chǔ)主要用來(lái)完成數(shù)據(jù)查詢(xún)和持久化操作。

倉(cāng)儲(chǔ)包括倉(cāng)儲(chǔ)的接口和倉(cāng)儲(chǔ)實(shí)現(xiàn),通過(guò)依賴(lài)倒置實(shí)現(xiàn)應(yīng)用業(yè)務(wù)邏輯與數(shù)據(jù)庫(kù)資源邏輯的解耦。

倉(cāng)儲(chǔ)代碼放在領(lǐng)域?qū)拥?Repository 目錄結(jié)構(gòu)下。

(四)代碼模型強(qiáng)調(diào)內(nèi)容

第一點(diǎn):聚合之間的代碼邊界一定要清晰。

聚合之間的服務(wù)調(diào)用和數(shù)據(jù)關(guān)聯(lián)應(yīng)該是盡可能的松耦合和低關(guān)聯(lián),聚合之間的服務(wù)調(diào)用應(yīng)該通過(guò)上層的應(yīng)用層組合實(shí)現(xiàn)調(diào)用,原則上不允許聚合之間直接調(diào)用領(lǐng)域服務(wù)。

這種松耦合的代碼關(guān)聯(lián),在以后業(yè)務(wù)發(fā)展和需求變更時(shí),可以很方便地實(shí)現(xiàn)業(yè)務(wù)功能和聚合代碼的重組,在微服務(wù)架構(gòu)演進(jìn)中將會(huì)起到非常重要的作用。

第二點(diǎn):你一定要有代碼分層的概念。

寫(xiě)代碼時(shí)一定要搞清楚代碼的職責(zé),將它放在職責(zé)對(duì)應(yīng)的代碼目錄內(nèi)。

應(yīng)用層代碼主要完成服務(wù)組合和編排,以及聚合之間的協(xié)作,它是很薄的一層,不應(yīng)該有核心領(lǐng)域邏輯代碼。

領(lǐng)域?qū)邮菢I(yè)務(wù)的核心,領(lǐng)域模型的核心邏輯代碼一定要在領(lǐng)域?qū)訉?shí)現(xiàn)。

如果將核心領(lǐng)域邏輯代碼放到應(yīng)用層,你的基于 DDD 分層架構(gòu)模型的微服務(wù)慢慢就會(huì)演變成傳統(tǒng)的三層架構(gòu)模型了。

三、正確理解微服務(wù)的邊界

微服務(wù)設(shè)計(jì)的重點(diǎn),就是看微服務(wù)設(shè)計(jì)是否能夠支持架構(gòu)長(zhǎng)期、輕松的演進(jìn)。

在事件風(fēng)暴中,我們會(huì)梳理出業(yè)務(wù)過(guò)程中的用戶(hù)操作、事件以及外部依賴(lài)關(guān)系等,根據(jù)這些要素梳理出實(shí)體等領(lǐng)域?qū)ο蟆?/p>

  • 根據(jù)實(shí)體對(duì)象之間的業(yè)務(wù)關(guān)聯(lián)性,將業(yè)務(wù)緊密相關(guān)的多個(gè)實(shí)體進(jìn)行組合形成聚合,聚合之間是第一層邊界。
  • 根據(jù)業(yè)務(wù)及語(yǔ)義邊界等因素將一個(gè)或者多個(gè)聚合劃定在一個(gè)限界上下文內(nèi),形成領(lǐng)域模型,限界上下文之間的邊界是第二層邊界。

為了方便理解,我們將這些邊界細(xì)分為:邏輯邊界、物理邊界和代碼邊界。

(一)邏輯邊界

邏輯邊界主要定義同一業(yè)務(wù)領(lǐng)域或應(yīng)用內(nèi)緊密關(guān)聯(lián)的對(duì)象所組成的不同聚類(lèi)的組合之間的邊界。

微服務(wù)內(nèi)聚合之間的邊界就是邏輯邊界。一般來(lái)說(shuō)微服務(wù)會(huì)有一個(gè)以上的聚合,在開(kāi)發(fā)過(guò)程中不同聚合的代碼隔離在不同的聚合代碼目錄中。它是一個(gè)虛擬的邊界,強(qiáng)調(diào)業(yè)務(wù)的內(nèi)聚,可根據(jù)需要變成物理邊界,也就是說(shuō)聚合也可以獨(dú)立為微服務(wù)。

微服務(wù)的架構(gòu)演進(jìn)并不是隨心所欲的,需要遵循一定的規(guī)則,這個(gè)規(guī)則就是邏輯邊界。微服務(wù)架構(gòu)演進(jìn)時(shí),在業(yè)務(wù)端以聚合為單位進(jìn)行業(yè)務(wù)能力的重組,在微服務(wù)端以聚合的代碼目錄為單位進(jìn)行微服務(wù)代碼的重組。

來(lái)看一個(gè)微服務(wù)實(shí)例,在下面這張圖中,我們可以看到微服務(wù)里包含了兩個(gè)聚合的業(yè)務(wù)邏輯,兩個(gè)聚合分別內(nèi)聚了各自不同的業(yè)務(wù)能力,聚合內(nèi)的代碼分別歸到了不同的聚合目錄下。

那隨著業(yè)務(wù)的快速發(fā)展,如果某一個(gè)微服務(wù)遇到了高性能挑戰(zhàn),需要將部分業(yè)務(wù)能力獨(dú)立出去,我們就可以以聚合為單位,將聚合代碼拆分獨(dú)立為一個(gè)新的微服務(wù),這樣就可以很容易地實(shí)現(xiàn)微服務(wù)的拆分。

另外,我們也可以對(duì)多個(gè)微服務(wù)內(nèi)有相似功能的聚合進(jìn)行功能和代碼重組,組合為新的聚合和微服務(wù),獨(dú)立為通用微服務(wù),有點(diǎn)做中臺(tái)的感覺(jué)!

(二)物理邊界

微服務(wù)之間的邊界是物理邊界。它強(qiáng)調(diào)微服務(wù)部署和運(yùn)行的隔離,關(guān)注微服務(wù)的服務(wù)調(diào)用、容錯(cuò)和運(yùn)行等。

物理邊界主要從部署和運(yùn)行的視角來(lái)定義微服務(wù)之間的邊界。不同微服務(wù)部署位置和運(yùn)行環(huán)境是相互物理隔離的,分別運(yùn)行在不同的進(jìn)程中。這種邊界就是微服務(wù)之間的物理邊界。

舉例:

有些項(xiàng)目團(tuán)隊(duì)在將集中式單體應(yīng)用拆分為微服務(wù)時(shí),首先進(jìn)行的往往不是建立領(lǐng)域模型,而只是按照業(yè)務(wù)功能將原來(lái)單體應(yīng)用的一個(gè)軟件包拆分成多個(gè)所謂的“微服務(wù)”軟件包,而這些“微服務(wù)”內(nèi)的代碼仍然是集中式三層架構(gòu)的模式,“微服務(wù)”內(nèi)的代碼高度耦合,邏輯邊界不清晰,這里我們暫且稱(chēng)它為“小單體微服務(wù)”。

而隨著新需求的提出和業(yè)務(wù)的發(fā)展,這些小單體微服務(wù)會(huì)慢慢膨脹起來(lái)。當(dāng)有一天你發(fā)現(xiàn)這些膨脹了的微服務(wù),有一部分業(yè)務(wù)功能需要拆分出去,或者部分功能需要與其它微服務(wù)進(jìn)行重組時(shí),你會(huì)發(fā)現(xiàn)原來(lái)這些看似清晰的微服務(wù),不知不覺(jué)已經(jīng)搖身一變,變成了臃腫油膩的大單體了,而這個(gè)大單體內(nèi)的代碼依然是高度耦合且邊界不清的。

這種單體式微服務(wù)只定義了一個(gè)維度的邊界,也就是微服務(wù)之間的物理邊界,本質(zhì)上還是單體架構(gòu)模式。微服務(wù)設(shè)計(jì)時(shí)要考慮的不僅僅只有這一個(gè)邊界,別忘了還要定義好微服務(wù)內(nèi)的邏輯邊界和代碼邊界,這樣才能得到你想要的結(jié)果。

(三)代碼邊界

不同層或者聚合之間代碼目錄的邊界是代碼邊界。它強(qiáng)調(diào)的是代碼之間的隔離,方便架構(gòu)演進(jìn)時(shí)代碼的重組。

代碼邊界主要用于微服務(wù)內(nèi)的不同職能代碼之間的隔離

微服務(wù)開(kāi)發(fā)過(guò)程中會(huì)根據(jù)代碼模型建立相應(yīng)的代碼目錄,實(shí)現(xiàn)不同功能代碼的隔離。由于領(lǐng)域模型與代碼模型的映射關(guān)系,代碼邊界直接體現(xiàn)出業(yè)務(wù)邊界。

代碼邊界可以控制代碼重組的影響范圍,避免業(yè)務(wù)和服務(wù)之間的相互影響。

微服務(wù)如果需要進(jìn)行功能重組,只需要以聚合代碼為單位進(jìn)行重組就可以了。

四、正確認(rèn)識(shí)服務(wù)和數(shù)據(jù)在微服務(wù)各層的協(xié)作

(一)正確認(rèn)識(shí)服務(wù)的協(xié)作

1. 服務(wù)的類(lèi)型

按照分層架構(gòu)設(shè)計(jì)出來(lái)的微服務(wù),其內(nèi)部有 Facade 服務(wù)、應(yīng)用服務(wù)、領(lǐng)域服務(wù)和基礎(chǔ)服務(wù)。之前都有提到,這里可以回憶一下!

2. 服務(wù)的調(diào)用(三類(lèi)主要場(chǎng)景)

微服務(wù)的服務(wù)調(diào)用包括三類(lèi)主要場(chǎng)景:微服務(wù)內(nèi)跨層服務(wù)調(diào)用,微服務(wù)之間服務(wù)調(diào)用和領(lǐng)域事件驅(qū)動(dòng)。

  • 微服務(wù)內(nèi)跨層服務(wù)調(diào)用

前端應(yīng)用調(diào)用發(fā)布在 API 網(wǎng)關(guān)上的 Facade 服務(wù),F(xiàn)acade 定向到應(yīng)用服務(wù)應(yīng)用服務(wù)作為服務(wù)組織和編排者,它的服務(wù)調(diào)用有這樣兩種路徑:

  • 第一種是應(yīng)用服務(wù)調(diào)用并組裝領(lǐng)域服務(wù)。此時(shí)領(lǐng)域服務(wù)會(huì)組裝實(shí)體和實(shí)體方法,實(shí)現(xiàn)核心領(lǐng)域邏輯。領(lǐng)域服務(wù)通過(guò)倉(cāng)儲(chǔ)服務(wù)獲取持久化數(shù)據(jù)對(duì)象,完成實(shí)體數(shù)據(jù)初始化。
  • 第二種是應(yīng)用服務(wù)直接調(diào)用倉(cāng)儲(chǔ)服務(wù)。這種方式主要針對(duì)像緩存、文件等類(lèi)型的基礎(chǔ)層數(shù)據(jù)訪(fǎng)問(wèn)。這類(lèi)數(shù)據(jù)主要是查詢(xún)操作,沒(méi)有太多的領(lǐng)域邏輯,不經(jīng)過(guò)領(lǐng)域?qū)樱簧婕皵?shù)據(jù)庫(kù)持久化對(duì)象。
  • 微服務(wù)之間的服務(wù)調(diào)用

微服務(wù)之間的應(yīng)用服務(wù)可以直接訪(fǎng)問(wèn),也可以通過(guò) API 網(wǎng)關(guān)訪(fǎng)問(wèn)

由于跨微服務(wù)操作,在進(jìn)行數(shù)據(jù)新增和修改操作時(shí),你需關(guān)注分布式事務(wù),保證數(shù)據(jù)的一致性。

  • 領(lǐng)域事件驅(qū)動(dòng)

領(lǐng)域事件驅(qū)動(dòng)包括微服務(wù)內(nèi)和微服務(wù)之間的事件。

  • 微服務(wù)內(nèi)通過(guò)事件總線(xiàn)(EventBus)完成聚合之間的異步處理。
  • 微服務(wù)之間通過(guò)消息中間件完成。異步化的領(lǐng)域事件驅(qū)動(dòng)機(jī)制是一種間接的服務(wù)訪(fǎng)問(wèn)方式。

當(dāng)應(yīng)用服務(wù)業(yè)務(wù)邏輯處理完成后,如果發(fā)生領(lǐng)域事件,可調(diào)用事件發(fā)布服務(wù),完成事件發(fā)布。

當(dāng)接收到訂閱的主題數(shù)據(jù)時(shí),事件訂閱服務(wù)會(huì)調(diào)用事件處理領(lǐng)域服務(wù),完成進(jìn)一步的業(yè)務(wù)操作。

3. 服務(wù)的封裝與組合

微服務(wù)的服務(wù)是從領(lǐng)域?qū)又鸺?jí)向上封裝、組合和暴露的。基本如下圖體現(xiàn):

(二)正確認(rèn)識(shí)服務(wù)數(shù)據(jù)的協(xié)作

在 DDD 中有很多的數(shù)據(jù)對(duì)象,這些對(duì)象分布在不同的層里。它們?cè)诓煌碾A段有不同的形態(tài):

  • 數(shù)據(jù)持久化對(duì)象 PO(Persistent Object),與數(shù)據(jù)庫(kù)結(jié)構(gòu)一一映射,是數(shù)據(jù)持久化過(guò)程中的數(shù)據(jù)載體。
  • 領(lǐng)域?qū)ο?DO(Domain Object),微服務(wù)運(yùn)行時(shí)的實(shí)體,是核心業(yè)務(wù)的載體。
  • 數(shù)據(jù)傳輸對(duì)象 DTO(Data Transfer Object),用于前端與應(yīng)用層或者微服務(wù)之間的數(shù)據(jù)組裝和傳輸,是應(yīng)用之間數(shù)據(jù)傳輸?shù)妮d體。
  • 視圖對(duì)象 VO(View Object),用于封裝展示層指定頁(yè)面或組件的數(shù)據(jù)。

微服務(wù)各層數(shù)據(jù)對(duì)象的職責(zé)和轉(zhuǎn)換過(guò)程如下:

1.基礎(chǔ)層數(shù)據(jù)協(xié)作

基礎(chǔ)層的主要對(duì)象是 PO 對(duì)象。

我們需要先建立 DO 和 PO 的映射關(guān)系

  • 當(dāng) DO 數(shù)據(jù)需要持久化時(shí),倉(cāng)儲(chǔ)服務(wù)會(huì)將 DO 轉(zhuǎn)換為 PO 對(duì)象,完成數(shù)據(jù)庫(kù)持久化操作。
  • 當(dāng) DO 數(shù)據(jù)需要初始化時(shí),倉(cāng)儲(chǔ)服務(wù)從數(shù)據(jù)庫(kù)獲取數(shù)據(jù)形成 PO 對(duì)象,并將 PO 轉(zhuǎn)換為 DO,完成數(shù)據(jù)初始化。

大多數(shù)情況下 PO 和 DO 是一一對(duì)應(yīng)的。但也有 DO 和 PO 多對(duì)多的情況,在 DO 和 PO 數(shù)據(jù)轉(zhuǎn)換時(shí),需要進(jìn)行數(shù)據(jù)重組。

2.領(lǐng)域?qū)訑?shù)據(jù)協(xié)作

領(lǐng)域?qū)拥闹饕獙?duì)象是 DO 對(duì)象。

DO 是實(shí)體和值對(duì)象的數(shù)據(jù)和業(yè)務(wù)行為載體,承載著基礎(chǔ)的核心業(yè)務(wù)邏輯。

通過(guò) DO 和 PO 轉(zhuǎn)換,我們可以完成數(shù)據(jù)持久化和初始化。

3.應(yīng)用層數(shù)據(jù)協(xié)作

應(yīng)用層的主要對(duì)象是 DO 對(duì)象。

如果需要調(diào)用其它微服務(wù)的應(yīng)用服務(wù),DO 會(huì)轉(zhuǎn)換為 DTO,完成跨微服務(wù)的數(shù)據(jù)組裝和傳輸。

用戶(hù)接口層先完成 DTO 到 DO 的轉(zhuǎn)換,然后應(yīng)用服務(wù)接收 DO 進(jìn)行業(yè)務(wù)處理。如果 DTO 與 DO 是一對(duì)多的關(guān)系,這時(shí)就需要進(jìn)行 DO 數(shù)據(jù)重組。

4.用戶(hù)接口層數(shù)據(jù)協(xié)作

用戶(hù)接口層會(huì)完成 DO 和 DTO 的互轉(zhuǎn),完成微服務(wù)與前端應(yīng)用數(shù)據(jù)交互及轉(zhuǎn)換。

Facade 服務(wù)會(huì)對(duì)多個(gè) DO 對(duì)象進(jìn)行組裝,轉(zhuǎn)換為 DTO 對(duì)象,向前端應(yīng)用完成數(shù)據(jù)轉(zhuǎn)換和傳輸。

5.前端應(yīng)用數(shù)據(jù)協(xié)作

前端應(yīng)用主要是 VO 對(duì)象。

展現(xiàn)層使用 VO 進(jìn)行界面展示,通過(guò)用戶(hù)接口層與應(yīng)用層采用 DTO 對(duì)象進(jìn)行數(shù)據(jù)交互。

參考書(shū)籍、文獻(xiàn)和資料

1.極客時(shí)間課程《DDD實(shí)戰(zhàn)》,歐創(chuàng)新,2019.

2.鄭天民. 微服務(wù)設(shè)計(jì)原理與架構(gòu). 北京:人民郵電出版社,2018.

3.陳超、秦金衛(wèi)、張逸等. 高可用可伸縮微服務(wù)架構(gòu). 電子工業(yè)出版社. 2019.

4.Eric Evans. 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)-軟件核心復(fù)雜性應(yīng)對(duì)之道。 人民郵電出版社. 2018.

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多