自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

DDD領(lǐng)域驅(qū)動(dòng)工程落地實(shí)戰(zhàn)

開(kāi)發(fā) 前端
DDD分為戰(zhàn)略設(shè)計(jì)與戰(zhàn)術(shù)設(shè)計(jì)。一般來(lái)說(shuō),領(lǐng)域建模是屬于戰(zhàn)略層的,而DDD工程落地是屬于戰(zhàn)術(shù)層的,兩者是否結(jié)合使用,視實(shí)際情況而定,比如傳統(tǒng)的MVC架構(gòu)也能使用DDD進(jìn)行領(lǐng)域建模,DDD架構(gòu)最好是先做DDD領(lǐng)域建模。

我在公司對(duì)支付業(yè)務(wù)、結(jié)算業(yè)務(wù)、資金業(yè)務(wù)使用DDD進(jìn)行領(lǐng)域建模的兩年,得到了許多好評(píng),也面對(duì)過(guò)不少質(zhì)疑,總體來(lái)說(shuō)還是能收獲不少,這對(duì)團(tuán)隊(duì)成員理解業(yè)務(wù)起著很大作用。近半年一直在研究DDD的落地實(shí)戰(zhàn),如今已修得階段性成果,迫不及待與大家分享我的落地經(jīng)驗(yàn)。

DDD分為戰(zhàn)略設(shè)計(jì)戰(zhàn)術(shù)設(shè)計(jì)。一般來(lái)說(shuō),領(lǐng)域建模是屬于戰(zhàn)略層的,而DDD工程落地是屬于戰(zhàn)術(shù)層的,兩者是否結(jié)合使用,視實(shí)際情況而定,比如傳統(tǒng)的MVC架構(gòu)也能使用DDD進(jìn)行領(lǐng)域建模,DDD架構(gòu)最好是先做DDD領(lǐng)域建模。?

最新上線的一個(gè)微服務(wù)——內(nèi)部交易中心,我們使用了DDD架構(gòu)來(lái)落地,希望看完對(duì)大家有啟發(fā)。

一、工程架構(gòu)分層理論

在工程落地之前,我們有必要先了解下主流的工程架構(gòu)或架構(gòu)思想都有哪些,對(duì)這些理論有所了解的,也可以直接跳過(guò)看下一個(gè)部分。

1、經(jīng)典DDD四層架構(gòu)

圖片

在該架構(gòu)中,上層模塊可以調(diào)用下層模塊,反之不行。即:

  • Interface ——> application | domain | infrastructure
  • application ——> domain | infrastructure
  • domain ——> infrastructure

分層作用:

  • 用戶(hù)界面層/表現(xiàn)層:負(fù)責(zé)向用戶(hù)顯示解釋用戶(hù)命令
  • 應(yīng)用層:定義軟件要完成的任務(wù),并且指揮協(xié)調(diào)領(lǐng)域?qū)ο筮M(jìn)行不同的操作。該層不包含業(yè)務(wù)領(lǐng)域知識(shí)
  • 領(lǐng)域?qū)?模型層:系統(tǒng)的核心,負(fù)責(zé)表達(dá)業(yè)務(wù)概念,業(yè)務(wù)狀態(tài)信息以及業(yè)務(wù)規(guī)則。即包含了該領(lǐng)域(問(wèn)題域)所有復(fù)雜的業(yè)務(wù)知識(shí)抽象和規(guī)則定義。該層主要精力要放在領(lǐng)域?qū)ο蠓治錾?,可以從?shí)體,值對(duì)象,聚合(聚合根),領(lǐng)域服務(wù),領(lǐng)域事件,倉(cāng)儲(chǔ),工廠等方面入手
  • 基礎(chǔ)設(shè)施層:一是為領(lǐng)域模型提供持久化機(jī)制,當(dāng)軟件需要持久化能力時(shí)候才需要進(jìn)行規(guī)劃;二是對(duì)其他層提供通用的技術(shù)支持能力,如消息通信,通用工具,配置等的實(shí)現(xiàn);

2、整潔架構(gòu)思想

整潔架構(gòu)(Clean Architecture)是由Bob大叔在2012年提出的一個(gè)架構(gòu)模型,顧名思義,是為了使架構(gòu)更簡(jiǎn)潔。

圖片

依賴(lài)規(guī)則:用一組同心圓來(lái)表示軟件的不同領(lǐng)域。一般來(lái)說(shuō),越深入代表你的軟件層次越高。外圓是戰(zhàn)術(shù)實(shí)現(xiàn)機(jī)制,內(nèi)圓的是核心原則。

這條規(guī)則規(guī)定軟件模塊只能向內(nèi)依賴(lài),而里面的部分對(duì)外面的模塊一無(wú)所知,也就是內(nèi)部不依賴(lài)外部,而外部依賴(lài)內(nèi)部。同樣,在外面圈中使用的數(shù)據(jù)格式不應(yīng)被內(nèi)圈中使用,特別是如果這些數(shù)據(jù)格式是由外面一圈的框架生成的。

這樣做的最大好處是當(dāng)系統(tǒng)的外部模塊不得不改變時(shí)(比如,替換已有的過(guò)時(shí)的數(shù)據(jù)庫(kù)系統(tǒng)),系統(tǒng)的內(nèi)層模塊不需要做任何改變。

3、六邊形架構(gòu)

六邊形架構(gòu)(Hexagonal Architecture),又叫做端口適配器模式,是由Alistair Cockburn在2005年提出的。

圖片

六邊形架構(gòu)將系統(tǒng)分為內(nèi)部(內(nèi)部六邊形)和外部,內(nèi)部代表了應(yīng)用的業(yè)務(wù)邏輯,外部代表應(yīng)用的驅(qū)動(dòng)邏輯、基礎(chǔ)設(shè)施或其他應(yīng)用。內(nèi)部通過(guò)端口和外部系統(tǒng)通信,端口代表了一定協(xié)議,以API呈現(xiàn)。

一個(gè)端口可能對(duì)應(yīng)多個(gè)外部系統(tǒng),不同的外部系統(tǒng)需要使用不同的適配器,適配器負(fù)責(zé)對(duì)協(xié)議進(jìn)行轉(zhuǎn)換。這樣就使得應(yīng)用程序能夠以一致的方式被用戶(hù)、程序、自動(dòng)化測(cè)試、批處理腳本所驅(qū)動(dòng),并且,可以在與實(shí)際運(yùn)行的設(shè)備和數(shù)據(jù)庫(kù)相隔離的情況下開(kāi)發(fā)和測(cè)試。

4、菱形架構(gòu)

作用于限界上下文的菱形對(duì)稱(chēng)架構(gòu)從領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)分層架構(gòu)與六邊形架構(gòu)中汲取了營(yíng)養(yǎng),通過(guò)對(duì)它們的融合形成了以領(lǐng)域?yàn)檩S心的內(nèi)外分層對(duì)稱(chēng)結(jié)構(gòu)。

圖片

內(nèi)部以領(lǐng)域?qū)拥念I(lǐng)域模型為主,外部的網(wǎng)關(guān)層則根據(jù)方向劃分為北向網(wǎng)關(guān)南向網(wǎng)關(guān)。通過(guò)該架構(gòu),可清晰說(shuō)明整個(gè)限界上下文的組成:

  • 北向網(wǎng)關(guān)的遠(yuǎn)程網(wǎng)關(guān)
  • 北向網(wǎng)關(guān)的本地網(wǎng)關(guān)
  • 領(lǐng)域?qū)拥念I(lǐng)域模型
  • 南向網(wǎng)關(guān)的端口抽象
  • 南向網(wǎng)關(guān)的適配器實(shí)現(xiàn)

限界上下文以領(lǐng)域模型為核心向南北方向?qū)ΨQ(chēng)發(fā)散,從而在邊界內(nèi)形成清晰的邏輯層次,前端UI并未包含在限界上下文的邊界之內(nèi)。每個(gè)組成元素之間的協(xié)作關(guān)系表現(xiàn)了清晰直觀的自北向南的調(diào)用關(guān)系。

5、CQRS

CQRS(Command Query Responsibility Segregation)意為命令查詢(xún)職責(zé)分離,它是一種與領(lǐng)域驅(qū)動(dòng)設(shè)計(jì) (DDD) 和事件溯源相關(guān)的架構(gòu)模式。Greg Young在2010年創(chuàng)造了這個(gè)術(shù)語(yǔ),CQRS的內(nèi)容基于Bertrand Meyer的CQS設(shè)計(jì)模式。

圖片

CQRS架構(gòu)將寫(xiě)入和讀取分開(kāi),它提出了單獨(dú)的 API,一個(gè)專(zhuān)用于更改應(yīng)用程序狀態(tài)的命令路由,另一個(gè)專(zhuān)用于返回有關(guān)應(yīng)用程序狀態(tài)信息的查詢(xún)路由。

二、工程架構(gòu)分層設(shè)計(jì)

基于各個(gè)架構(gòu)有其自己的優(yōu)缺點(diǎn),我們結(jié)合公司的現(xiàn)狀,取其長(zhǎng)避其短,融合一套適合自己的架構(gòu)。

圖片

  • 以經(jīng)典DDD四層架構(gòu)為骨架,其他優(yōu)秀架構(gòu)思想作指導(dǎo)
  • CQRS命令/查詢(xún)職責(zé)分離,應(yīng)用到DDD應(yīng)用層,處理復(fù)雜操作/復(fù)雜查詢(xún)
  • 整潔架構(gòu)應(yīng)用到DDD領(lǐng)域?qū)优c基礎(chǔ)設(shè)施層,接口與實(shí)現(xiàn)拆到不同層,把技術(shù)代碼與業(yè)務(wù)代碼分離
  • 菱形架構(gòu)指導(dǎo)我們,內(nèi)部以領(lǐng)域?qū)拥念I(lǐng)域模型為主,向南北兩個(gè)方法發(fā)散——北向網(wǎng)關(guān)(領(lǐng)域?qū)右陨希┨峁┍镜鼐W(wǎng)關(guān)(如Controller、MQListener)與遠(yuǎn)程網(wǎng)關(guān)(如API包);南向網(wǎng)關(guān)(領(lǐng)域?qū)右韵拢┴?fù)責(zé)端口抽象(如倉(cāng)庫(kù)接口)與適配器實(shí)現(xiàn)(如外部API封裝實(shí)現(xiàn))
  • 公司的Base框架在dal包封裝了基礎(chǔ)CRUD接口,應(yīng)用到數(shù)據(jù)訪問(wèn)層內(nèi),作為領(lǐng)域?qū)优c基礎(chǔ)設(shè)施層的粘合劑,簡(jiǎn)化鏈接

當(dāng)然,任何事物有其兩面性,融合各個(gè)框架后,也有其優(yōu)缺點(diǎn)——

優(yōu)點(diǎn):通過(guò)分離業(yè)務(wù)與技術(shù)代碼,有利于業(yè)務(wù)迭代升級(jí)維護(hù);業(yè)務(wù)驅(qū)動(dòng)而非技術(shù)/數(shù)據(jù)驅(qū)動(dòng),通過(guò)寫(xiě)代碼就能積累一定的業(yè)務(wù)知識(shí);將領(lǐng)域知識(shí)和技術(shù)知識(shí)分類(lèi),從而提高代碼的可重用性。

缺點(diǎn):對(duì)從業(yè)人員業(yè)務(wù)分析能力較高,難以從經(jīng)典MVC架構(gòu)轉(zhuǎn)變過(guò)來(lái);層級(jí)較多,寫(xiě)代碼前需考慮清楚邏輯應(yīng)該寫(xiě)在哪一層;規(guī)則較多,沒(méi)有MVC架構(gòu)靈活,不適用于簡(jiǎn)單業(yè)務(wù)系統(tǒng);學(xué)習(xí)成本與轉(zhuǎn)移成本比較高,需要對(duì)DDD有更好的理解和更長(zhǎng)的設(shè)計(jì)時(shí)間(資金組踐行DDD領(lǐng)域建模2年)。

三、工程代碼構(gòu)建案例

圖片

看代碼之前我們先看下領(lǐng)域建模:

通過(guò)領(lǐng)域模型分析,內(nèi)部交易中心分為內(nèi)部調(diào)貨、規(guī)則中心、內(nèi)部出入庫(kù)、內(nèi)部銷(xiāo)售、內(nèi)部采購(gòu)這五大模塊,每一個(gè)模塊對(duì)應(yīng)DDD就是一個(gè)聚合,所有聚合形成一個(gè)DDD的限界上下文(內(nèi)部交易上下文),之前的文章提到,限界上下文就是我們劃分微服務(wù)的一個(gè)重要依據(jù)。

接下來(lái),我們結(jié)合DDD架構(gòu)圖與領(lǐng)域建模,看看工程代碼應(yīng)該怎么放。

圖片

基于Maven的DDD工程,頂層結(jié)構(gòu)我們按api、service劃分為兩個(gè)module。

api包的作用:

  • api包的定位是跨服務(wù)的頂層契約,service包所有層都可以依賴(lài)api包
  • api包定義了對(duì)外透出的枚舉/常量、入?yún)ⅰ⒊鰠?、API接口等,為了方便使用api類(lèi),feign層不作業(yè)務(wù)劃分
  • api包只定義契約不寫(xiě)業(yè)務(wù)邏輯,避免因業(yè)務(wù)邏輯變更引發(fā)的api包升級(jí)

service包的作用:

  • service包是工程的頂層實(shí)現(xiàn),DDD四層架構(gòu)在service包體現(xiàn)
  • Application程序入口與DDD的四層處于同一目錄

此外,針對(duì)service包還有另一種主流的module劃分方式——直接把service包的api、application、domain、infrastructure作為四個(gè)獨(dú)立的module,優(yōu)點(diǎn)是能通過(guò)pom依賴(lài)的方式來(lái)限制層與層之間的依賴(lài),開(kāi)發(fā)人員能在編碼階段發(fā)現(xiàn)依賴(lài)問(wèn)題及時(shí)修正,但缺點(diǎn)也明顯——不夠靈活,工程也會(huì)變得較重。

1、接入層(api)

圖片

接入層又叫用戶(hù)接入層,主流用interface或api命名,基于包默認(rèn)按字母排序的原因,我建議使用“api”來(lái)命名接入層,但要注意,service包的api層與api包是不同的作用。

  • 接入層是很薄的一層,負(fù)責(zé)直接對(duì)接前端請(qǐng)求或feign實(shí)現(xiàn)(facade里的Controller)、數(shù)據(jù)轉(zhuǎn)換(assembler),入?yún)?出參等契約類(lèi)(request/response)統(tǒng)一定義在頂層的api包
  • Controller負(fù)責(zé)對(duì)數(shù)據(jù)做前置校驗(yàn),具體業(yè)務(wù)邏輯則交給應(yīng)用服務(wù)或領(lǐng)域服務(wù)實(shí)現(xiàn),可直接調(diào)用應(yīng)用服務(wù)方法或領(lǐng)域方法
  • 業(yè)務(wù)劃分在接入層不明顯,更多是基于前端模塊進(jìn)行劃分Controller,且業(yè)務(wù)復(fù)雜時(shí)必然存在領(lǐng)域交叉,故facade下沒(méi)有再細(xì)分業(yè)務(wù)包
  • assembler數(shù)據(jù)轉(zhuǎn)換負(fù)責(zé)處理復(fù)雜的數(shù)據(jù)轉(zhuǎn)換,簡(jiǎn)單的數(shù)據(jù)轉(zhuǎn)換可顯式調(diào)用工具類(lèi)的轉(zhuǎn)換方法

2、應(yīng)用層(application)

圖片

應(yīng)用層主要作用是業(yè)務(wù)編排、轉(zhuǎn)發(fā)、校驗(yàn)等,處理跨聚合、領(lǐng)域事件邏輯,復(fù)雜操作/復(fù)雜查詢(xún)也在此層體現(xiàn)(CQRS)。

  • 應(yīng)用服務(wù)AppService是一種簡(jiǎn)單邏輯封裝,接入層無(wú)法直接調(diào)用領(lǐng)域?qū)幽玫浇Y(jié)果的,可在此層編排封裝聚合方法
  • 應(yīng)用層可依賴(lài)領(lǐng)域?qū)?,但不可依?lài)接入層,所以傳參進(jìn)應(yīng)用層要么是基礎(chǔ)類(lèi)型,要么在接入層assembler做一層轉(zhuǎn)換,要么入?yún)⒊鰠⒍x在api包
  • 事件一般情況是跨聚合或跨服務(wù)的,所以事件定義在應(yīng)用層,在應(yīng)用層處理事件的發(fā)布/訂閱
  • 接入層可直接調(diào)用領(lǐng)域?qū)樱唤?jīng)過(guò)應(yīng)用層

3、領(lǐng)域?qū)樱╠omain)

圖片

領(lǐng)域?qū)踊蚍Q(chēng)為模型層,系統(tǒng)的核心,負(fù)責(zé)表達(dá)業(yè)務(wù)概念、業(yè)務(wù)狀態(tài)信息以及業(yè)務(wù)規(guī)則,包含了該領(lǐng)域所有復(fù)雜的業(yè)務(wù)知識(shí)抽象和規(guī)則定義。

  • 領(lǐng)域?qū)又槐磉_(dá)業(yè)務(wù),不寫(xiě)技術(shù)代碼,在業(yè)務(wù)上不依賴(lài)其他層
  • 領(lǐng)域聚合以業(yè)務(wù)來(lái)命名包,聚合內(nèi)包含該聚合下所有模型(DO對(duì)象)、倉(cāng)庫(kù)接口、領(lǐng)域服務(wù)
  • 領(lǐng)域模型model是領(lǐng)域聚合下的業(yè)務(wù)核心模型,以XxxDO命名,依舊采用貧血模型,只包含少量原子性操作,不包含跨模型數(shù)據(jù)處理、持久化操作等
  • 倉(cāng)庫(kù)使用repository命名,領(lǐng)域?qū)又欢x倉(cāng)庫(kù)接口,不寫(xiě)倉(cāng)庫(kù)實(shí)現(xiàn)
  • 領(lǐng)域工廠factory與設(shè)計(jì)模式里的工廠模式不同,領(lǐng)域工廠主要負(fù)責(zé)領(lǐng)域?qū)ο蟮膹?fù)雜構(gòu)建,如領(lǐng)域?qū)ο笊?、屬性填充等,由于存在跨聚合的情況,所以factory包并不在聚合內(nèi),與領(lǐng)域聚合同層級(jí)
  • 外部API接口、外部框架代碼做一層淺封裝,放在external聚合包下,以ExXxxService命名接口,實(shí)現(xiàn)類(lèi)還是在基礎(chǔ)設(shè)施層,起接口防腐作用

圖片

因?yàn)轭I(lǐng)域建模最終體現(xiàn)在領(lǐng)域?qū)觾?nèi),在我們建模時(shí)就要考慮領(lǐng)域?qū)拥拇a如何寫(xiě)。

  • 領(lǐng)域建模時(shí)只表達(dá)核心屬性與核心行為
  • 聚合內(nèi)跨多個(gè)模型的復(fù)雜業(yè)務(wù)邏輯,寫(xiě)在領(lǐng)域服務(wù)內(nèi)
  • 領(lǐng)域模型的方法只寫(xiě)原子性的操作,但不包括CRUD持久化操作

一些難點(diǎn):

  • 無(wú)法實(shí)現(xiàn)模型的“所建即所得”,復(fù)雜代碼無(wú)法通過(guò)領(lǐng)域模型的簡(jiǎn)單幾個(gè)方法表達(dá)完整
  • 模型只能表達(dá)核心的業(yè)務(wù)行為,所謂的充血模型在落地時(shí)可能更多地拆分到領(lǐng)域工廠、領(lǐng)域服務(wù)、應(yīng)用服務(wù)中實(shí)現(xiàn)

4、基礎(chǔ)設(shè)施層(infrastructure)

圖片

基礎(chǔ)設(shè)施層作為工程的基礎(chǔ)設(shè)施使用,編寫(xiě)與業(yè)務(wù)無(wú)關(guān)的代碼,如技術(shù)框架、工具類(lèi),此外還有一個(gè)重要的功能,要寫(xiě)倉(cāng)庫(kù)的實(shí)現(xiàn)類(lèi)、外部服務(wù)的實(shí)現(xiàn)類(lèi)。

  • 基礎(chǔ)設(shè)施層的倉(cāng)庫(kù)(repository)實(shí)現(xiàn)了領(lǐng)域?qū)佣x的倉(cāng)庫(kù)接口,數(shù)據(jù)訪問(wèn)層(dao)也定義在倉(cāng)庫(kù)下,數(shù)據(jù)庫(kù)實(shí)體(PO對(duì)象)定義在entity,以XxxPO或XxxEntity命名,這里遵循了公司框架的命名方式,使用了XxxEntity
  • param是比較特殊的一層,該類(lèi)一般定義查詢(xún)數(shù)據(jù)庫(kù)的參數(shù)。基于公司的Base框架,repository定義接口時(shí)依賴(lài)了param對(duì)象,按道理領(lǐng)域?qū)硬粦?yīng)依賴(lài)基礎(chǔ)設(shè)施層(DIP原則),但Param又跟PO對(duì)象息息相關(guān),所以把param對(duì)象放在了基礎(chǔ)設(shè)施層
  • 基于Clean架構(gòu)原則,其他框架性代碼、工具類(lèi)、配置類(lèi)都放在基礎(chǔ)設(shè)施層,業(yè)務(wù)代碼與技術(shù)代碼分離后,萬(wàn)一升級(jí)技術(shù)代碼,對(duì)業(yè)務(wù)代碼做最少改動(dòng)

我們?cè)賮?lái)看一下全貌:

圖片

圖片

通過(guò)實(shí)際案例,總結(jié)以下重要幾點(diǎn):

  • 領(lǐng)域?qū)邮菢I(yè)務(wù)最核心的一層,聚合之間的邊界需要?jiǎng)澐智逦尤雽?、?yīng)用層涉及跨聚合,基礎(chǔ)設(shè)施層關(guān)注倉(cāng)儲(chǔ)實(shí)現(xiàn)與技術(shù)框架,所以我們只在領(lǐng)域?qū)觿澐謽I(yè)務(wù)包,對(duì)應(yīng)領(lǐng)域建模按聚合劃分邊界,并定義領(lǐng)域模型的倉(cāng)儲(chǔ)接口
  • 充血模型建模,貧血模型落地,把核心業(yè)務(wù)行為按需劃分到領(lǐng)域模型(原子性、非持久化)、領(lǐng)域工廠(構(gòu)建模型)、領(lǐng)域服務(wù)(跨模型)或應(yīng)用服務(wù)(跨聚合、事件)中
  • 使用接口分離業(yè)務(wù)代碼與技術(shù)性代碼,當(dāng)業(yè)務(wù)迭代時(shí),修改領(lǐng)域?qū)雍突A(chǔ)設(shè)施層的倉(cāng)庫(kù)實(shí)現(xiàn)即可;當(dāng)技術(shù)框架升級(jí)時(shí),修改基礎(chǔ)設(shè)施層即可,不至于把業(yè)務(wù)代碼也修改一遍,減少出錯(cuò)成本

DDD工程落地考慮的是代碼的歸類(lèi)劃分問(wèn)題,重點(diǎn)在于業(yè)務(wù)邊界的識(shí)別、業(yè)務(wù)和技術(shù)代碼的解耦。寫(xiě)代碼前需要考慮清楚不同的代碼應(yīng)該寫(xiě)到哪里,結(jié)合前人優(yōu)秀的工程架構(gòu)思路與公司當(dāng)前的技術(shù)架構(gòu),整合一套靈活的、適合我們自己的DDD,不能照搬,更不能為了DDD而DDD。

四、疑難分析

1、用充血模型還是貧血模型?

其實(shí)除了常見(jiàn)的充血模型、貧血模型,還有不常用的失血模型、脹血模型,區(qū)別如下:

  • 失血模型:只包含Getter/Setter的純數(shù)據(jù)類(lèi),一般不會(huì)有這種設(shè)計(jì)
  • 貧血模型:包含模型屬性、Getter/Setter與非持久化的原子領(lǐng)域邏輯,持久化邏輯放在業(yè)務(wù)層(如Service類(lèi))
  • 充血模型:比貧血模型多了持久化操作與絕大多數(shù)業(yè)務(wù)邏輯,實(shí)例化時(shí)會(huì)拿到很多不一定需要的關(guān)聯(lián)模型
  • 脹血模型:只有領(lǐng)域?qū)ο笈cDAO兩層,在領(lǐng)域邏輯上封裝事務(wù)

基于現(xiàn)有的Spring框架,以及個(gè)人以往的代碼編寫(xiě)經(jīng)驗(yàn),在代碼落地層面還是以貧血模型進(jìn)行較恰當(dāng)。

2、放應(yīng)用服務(wù)還是領(lǐng)域服務(wù)?

應(yīng)用服務(wù)在應(yīng)用層,領(lǐng)域服務(wù)在領(lǐng)域?qū)?,我怎么知道業(yè)務(wù)代碼該放哪里?

應(yīng)用服務(wù)的作用:

  • 負(fù)責(zé)展現(xiàn)層與領(lǐng)域?qū)又g的協(xié)調(diào),協(xié)調(diào)業(yè)務(wù)對(duì)象來(lái)執(zhí)行特定的應(yīng)用程序任務(wù)(編排業(yè)務(wù))
  • 放相對(duì)靈活的代碼邏輯,易于編排
  • 操作粒度較大,事務(wù)管理在此處理

領(lǐng)域服務(wù)的作用:

  • 負(fù)責(zé)表達(dá)業(yè)務(wù)概念,業(yè)務(wù)狀態(tài)信息以及業(yè)務(wù)規(guī)則,是業(yè)務(wù)軟件的核心
  • 放相對(duì)原子性的核心代碼,封裝性與復(fù)用性強(qiáng)
  • 操作粒度較細(xì),不管理事務(wù),領(lǐng)域模型不應(yīng)該意識(shí)到事務(wù)的存在

其實(shí),難點(diǎn)在于識(shí)別業(yè)務(wù)代碼,考驗(yàn)我們對(duì)業(yè)務(wù)的理解程度與思考程度,如果可以顯然預(yù)料到未來(lái)會(huì)發(fā)生明顯的變化,則應(yīng)該在設(shè)計(jì)之初更靈活地設(shè)計(jì)好;如果對(duì)未來(lái)的變化把握并不清晰或不確定,滿(mǎn)足當(dāng)前業(yè)務(wù)需求即可。

我們無(wú)法避免過(guò)度設(shè)計(jì)還是設(shè)計(jì)不足,但如果架構(gòu)合理,代碼清晰,改起來(lái)成本不會(huì)特別大。這里提倡開(kāi)發(fā)者盡量多與領(lǐng)域?qū)<遥I(yè)務(wù)人員或產(chǎn)品經(jīng)理)溝通,以把握代碼未來(lái)的走向。

3、特殊代碼如何歸類(lèi)?

除了常規(guī)的簡(jiǎn)單業(yè)務(wù)代碼,還涉及到復(fù)雜業(yè)務(wù)代碼拆分到不同類(lèi)的問(wèn)題,最典型的是運(yùn)用設(shè)計(jì)模式。

  • 工廠模式:根據(jù)不同條件生成相應(yīng)對(duì)象,常見(jiàn)領(lǐng)域工廠、領(lǐng)域服務(wù)、應(yīng)用服務(wù)內(nèi)
  • 策略模式:根據(jù)不同條件執(zhí)行相應(yīng)邏輯,定義一個(gè)策略接口和多個(gè)策略實(shí)現(xiàn),常見(jiàn)領(lǐng)域服務(wù)、應(yīng)用服務(wù)內(nèi)
  • 觀察者模式:使用發(fā)布/訂閱模式代替,可運(yùn)用基礎(chǔ)設(shè)施層的SpringEvent來(lái)解耦代碼
  • 責(zé)任鏈模式:拆分復(fù)雜業(yè)務(wù)邏輯到各個(gè)責(zé)任鏈類(lèi)執(zhí)行,常見(jiàn)領(lǐng)域服務(wù)、應(yīng)用服務(wù)內(nèi)

原則上,核心邏輯在哪一層拆就放在哪一層,避免代碼散落到各處。

五、一些經(jīng)驗(yàn)

?DDD領(lǐng)域建模三大步:劃分邊界、統(tǒng)一語(yǔ)言、組織模型。

DDD工程落地四大步:整合框架思想、確定劃分思路、模型代碼映射、特殊代碼歸類(lèi)。?

以上,從DDD領(lǐng)域建模到DDD工程落地實(shí)戰(zhàn)已全篇完結(jié),也歡迎大家一起來(lái)探討,如需要DDD工程的Demo也可以聯(lián)系我。

我相信80%的技術(shù)面試官都會(huì)對(duì)DDD這塊感興趣,如果你也掌握了DDD,其實(shí)就多掌握了一種面向RMB編程。

責(zé)任編輯:姜華 來(lái)源: 架構(gòu)師修行錄
相關(guān)推薦

2022-07-17 07:37:29

微服務(wù)DDD工程化落地

2022-02-24 09:22:52

領(lǐng)域驅(qū)動(dòng)成本

2021-09-08 09:22:23

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)

2021-10-09 11:54:46

DDD微服務(wù)業(yè)務(wù)

2017-07-14 10:55:05

2020-09-02 08:12:05

CodeDDD代碼

2023-01-09 09:00:00

樹(shù)服務(wù)架構(gòu)驅(qū)動(dòng)決策

2014-09-26 10:00:25

驅(qū)動(dòng)設(shè)計(jì)DDD領(lǐng)域

2024-11-08 08:37:25

2024-11-27 15:33:17

軟件架構(gòu)DDD

2022-04-19 08:15:53

DDD領(lǐng)域建模實(shí)戰(zhàn)

2024-12-31 11:05:07

2022-02-10 10:28:34

數(shù)據(jù)庫(kù)方案實(shí)踐

2021-11-18 13:14:08

DDD聚合代碼

2024-07-17 08:12:06

2022-10-08 09:18:19

架構(gòu)模型

2023-02-19 12:44:07

領(lǐng)域事件DDD

2023-02-26 10:59:51

2023-08-28 07:28:41

項(xiàng)目領(lǐng)域?qū)?/a>充血模型

2022-08-29 09:14:01

戰(zhàn)略設(shè)計(jì)核心域支撐域
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)