領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)-落地技能

1 界限上下文

限界上下文確實(shí)和劃分模塊、劃分子系統(tǒng)一樣,是一種分而治之的手段,可以起到分離關(guān)注點(diǎn)的作用。但限界上下文增加了一個(gè)要點(diǎn),就是,它的目的還在于維護(hù)概念一致性。正是這一點(diǎn),造成限界上下文和傳統(tǒng)方法的本質(zhì)不同。

當(dāng)系統(tǒng)達(dá)到一定規(guī)模,就超過(guò)了一個(gè)團(tuán)隊(duì)的認(rèn)知能力,無(wú)法保證概念的一致性了。這時(shí)候,就要把大系統(tǒng)分解成若干子系統(tǒng),每個(gè)子系統(tǒng)對(duì)應(yīng)一個(gè)領(lǐng)域模型。每個(gè)模型的規(guī)模都不超過(guò)一個(gè)開(kāi)發(fā)小組的認(rèn)知負(fù)載。

在每個(gè)子系統(tǒng)的內(nèi)部實(shí)現(xiàn)概念的嚴(yán)格一致性,而不同系統(tǒng)內(nèi)部之間則沒(méi)有必要一致。也就是說(shuō),不再追求全局一致性,而是退而求其次,只需追求局部的一致性,使概念不一致的問(wèn)題得到合理管控,從而實(shí)現(xiàn)業(yè)務(wù)目標(biāo),這樣就足夠了。

舉個(gè)例子:

  • “項(xiàng)目”和“基礎(chǔ)信息管理”分別屬于兩個(gè)不同的領(lǐng)域模型。
  • 在項(xiàng)目領(lǐng)域模型里面,有用到“員工”信息。
  • 員工是屬于基礎(chǔ)信息領(lǐng)域模型里面的。

項(xiàng)目管理中的員工是從基礎(chǔ)信息管理上下文里“映射”過(guò)來(lái)的。兩個(gè)上下文之間的這種映射關(guān)系,可以用<<map from>>來(lái)表示員工是從另一個(gè)領(lǐng)域模型里面映射過(guò)來(lái)的,bounded context = 基礎(chǔ)信息管理,就表示另一個(gè)領(lǐng)域模型是基礎(chǔ)信息管理。


image.png

1.2 防腐層

還是上面那個(gè)例子,在“項(xiàng)目”里面,想要拿到員工Emp信息,那么在系統(tǒng)里面,就會(huì)有兩個(gè)Emp類,“基礎(chǔ)信息管理”里面的 Emp 帶有工作經(jīng)驗(yàn)和技能,并且屬性會(huì)更多;而“工時(shí)管理”里面的 Emp 沒(méi)有工作經(jīng)驗(yàn)和技能信息,而且只有少數(shù)幾個(gè)要用到的屬性。那么這兩個(gè) Emp 轉(zhuǎn)換發(fā)生在哪里呢?

轉(zhuǎn)換就發(fā)生在“項(xiàng)目”里面的員工倉(cāng)庫(kù),也就是 EmpRepository 的實(shí)現(xiàn)里。

倉(cāng)庫(kù)的實(shí)現(xiàn)封裝了對(duì)其他上下文的調(diào)用。如果將來(lái),“基礎(chǔ)信息管理”的 API 和 DTO 改變了,那么只需要改 EmpRositoryImpl 內(nèi)部的邏輯就可以了,“工時(shí)管理”的其他部分都不需要修改。EmpRositoryImpl 就充當(dāng)了防腐層的作用。

DDD 中,防腐層也是一種用于上下文映射的模式。指的是兩個(gè)上下文之間的轉(zhuǎn)換邏輯,這個(gè)邏輯可以屏蔽兩個(gè)上下文的差異,從而使兩個(gè)上下文可以相對(duì)獨(dú)立地演進(jìn)。

2 CQRS

CQRS 是 Command Query Responsibility Segregation 的簡(jiǎn)稱,中文是 “命令查詢職責(zé)分離”。這個(gè)名字乍聽(tīng)起來(lái)也不太好理解,咱們還是從業(yè)務(wù)需求開(kāi)始,一步一步地理解。

前人已經(jīng)意識(shí)到了查詢和其他功能的不同之處,主張采用不同的方式來(lái)處理查詢邏輯,并提出了所謂 CQRS 架構(gòu)。

最早提出這個(gè)說(shuō)法的是 Greg Young。他把增、刪、改功能稱為 Command(命令),把查詢稱為 Query,這兩種功能的職責(zé)不同,應(yīng)該采用不同的方式來(lái)處理,因此叫做“命令查詢職責(zé)分離”(Command Query Responsibility Segregation ),簡(jiǎn)稱 CQRS。

盡管通過(guò) DDD 的領(lǐng)域模型完成增、刪、改等功能是很適合的,但是通過(guò)領(lǐng)域模型來(lái)實(shí)現(xiàn)查詢功能,常常是比較繁瑣的,而且性能也不高。因此, CQRS 就成了 DDD 的有力補(bǔ)充。

實(shí)現(xiàn)CQRS有兩種模式:

  • 應(yīng)用分離:把寫(xiě)操作和讀操作分為兩個(gè)不同的服務(wù),訪問(wèn)同一個(gè)數(shù)據(jù)庫(kù)。
  • 數(shù)據(jù)庫(kù)分離:還是拆分成讀服務(wù)和寫(xiě)服務(wù),同時(shí)呢,也為讀服務(wù)冗余一個(gè)讀庫(kù)(違背DB范式,冗余字段),簡(jiǎn)化讀服務(wù)的查詢操作。

3 DDD推廣

三種常見(jiàn)的切入場(chǎng)景:

  • 第一種是新建系統(tǒng)。也就是說(shuō)現(xiàn)在剛好有一個(gè)新項(xiàng)目,可能是要開(kāi)發(fā)一個(gè)全新的系統(tǒng),也可能是為現(xiàn)有系統(tǒng)新增或重寫(xiě)一個(gè)比較大的模塊。
  • 第二種是改造現(xiàn)有系統(tǒng)。常見(jiàn)的情況是,某個(gè)對(duì)公司很有價(jià)值的系統(tǒng),已經(jīng)維護(hù)了很多年,系統(tǒng)架構(gòu)和質(zhì)量日益腐化,很難維護(hù),不能滿足快速變化的業(yè)務(wù)需求。
  • 第三種是改進(jìn)現(xiàn)有研發(fā)流程。公司未必想專門(mén)花一大筆預(yù)算新建或者改造系統(tǒng),但領(lǐng)導(dǎo)已經(jīng)意識(shí)到目前的研發(fā)流程有種種不足,如果再“野蠻生長(zhǎng)”下去,會(huì)有很大的隱患。因此希望通過(guò)引入 DDD 等方法,提高研發(fā)水平和效能。

改造現(xiàn)有系統(tǒng)的步驟:


1705503480435.png
  • 第一步是反推領(lǐng)域模型。目的是客觀地反映出系統(tǒng)當(dāng)前的領(lǐng)域知識(shí)和邏輯。這時(shí)候的模型往往有不少問(wèn)題,比如不能正確反映領(lǐng)域知識(shí)、存在矛盾、冗余等。
  • 第二步是建立目標(biāo)領(lǐng)域模型。根據(jù)當(dāng)前系統(tǒng)的痛點(diǎn)、問(wèn)題以及業(yè)務(wù)需求,就可以建立目標(biāo)領(lǐng)域模型,作為改進(jìn)的方向。建立目標(biāo)領(lǐng)域模型,一定要有明確的“時(shí)間點(diǎn)”。
  • 第三步是設(shè)計(jì)演進(jìn)路線。一般要把改進(jìn)過(guò)程化整為零,迭代實(shí)施,并且還要兼顧日常的業(yè)務(wù)需求,后面我們還會(huì)提到這個(gè)問(wèn)題。
  • 第四步是迭代實(shí)施。最好基于敏捷軟件開(kāi)發(fā)方法,小步快跑地實(shí)施。在這個(gè)過(guò)程中,必然會(huì)對(duì)之前建立的目標(biāo)領(lǐng)域模型進(jìn)行反饋,不斷改進(jìn)。同時(shí)還要不斷評(píng)估開(kāi)發(fā)現(xiàn)狀,保證不偏離目標(biāo)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容