領(lǐng)域驅(qū)動(dòng)設(shè)計(jì): 服務(wù)邊界劃分

DDD是什么?

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)是一種處理高度復(fù)雜域的設(shè)計(jì)方法,試圖分離技術(shù)實(shí)現(xiàn)的復(fù)雜性,圍繞業(yè)務(wù)概念構(gòu)建領(lǐng)域模型來控制業(yè)務(wù)的復(fù)雜性,以解決軟件難以理解,難以演化等問題。團(tuán)隊(duì)?wèi)?yīng)用它可以成功地開發(fā)復(fù)雜業(yè)務(wù)軟件系統(tǒng),使系統(tǒng)在演進(jìn)時(shí)任然保持敏捷。

另外一種解讀:DDD不是語言,不是框架,不是架構(gòu),而是一種思想,一種套路,它可以分離業(yè)務(wù)復(fù)雜度和技術(shù)復(fù)雜度,DDD也并不是一個(gè)新的事物,它是面向?qū)ο蟮陌胃?,最終目標(biāo)還是

高內(nèi)聚,底耦合

DDD主要解決的問題?

  1. 如何合理的劃分業(yè)務(wù)系統(tǒng)?
    這為微服務(wù)的劃分提供了方法論(微服務(wù)的粒度的問題,多大算大,多小又算小,在微服務(wù)剛興起時(shí),很多企業(yè)或者架構(gòu)師對(duì)它都沒有統(tǒng)一且明確的定義,這里給些examples,e.g:代碼行數(shù)?職責(zé)的劃分?披薩原則?組織結(jié)構(gòu)?)界限上下文很好的回答了這個(gè)問題,這也是DDD最近幾年借微服務(wù)的東風(fēng),火起來的原因之一(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的提出距今已經(jīng)十多年,但真正火熱起來大約是在2013年微服務(wù)架構(gòu)被提出來之后)。

  2. 如何保持業(yè)務(wù)架構(gòu)和系統(tǒng)架構(gòu)的一致性?
    與傳統(tǒng)的系統(tǒng)相比,DDD里面強(qiáng)調(diào)領(lǐng)域?qū)<液图夹g(shù)團(tuán)隊(duì)的合作,建立統(tǒng)一語言“普通話”, 聚焦在領(lǐng)域,領(lǐng)域邏輯和業(yè)務(wù)流程上面,使整體團(tuán)隊(duì)對(duì)同一個(gè)業(yè)務(wù)術(shù)語有統(tǒng)一的認(rèn)識(shí),避免理解的偏差,并將這些“術(shù)語”映射到代碼中,隨著系統(tǒng)的演進(jìn)變遷。

DDD戰(zhàn)略設(shè)計(jì)?

戰(zhàn)略設(shè)計(jì).png

DDD領(lǐng)域劃分?

根據(jù)問題域,將問題劃分為Core domain,Sub domain, Support subdomain和generic subdomian,大概標(biāo)準(zhǔn)如下:

  1. 核心域:核心競(jìng)爭(zhēng)力,核心業(yè)務(wù) (需要投入最好的人力和資源)
  2. 支持子域: 沒有,很糟糕; 有,也不足以脫穎而出(可以考慮外包)
  3. 通用子域:都有的東西, 比如認(rèn)證, 發(fā)短信, 客服系統(tǒng)等(可以考慮購(gòu)買商業(yè)解決方案或者采用開源方案)

DDD領(lǐng)域建模方法?

領(lǐng)域建模的方式很多種,比如四色建模、OOAD還有事件風(fēng)暴,我們這里只簡(jiǎn)單聊聊如何使用事件風(fēng)暴梳理業(yè)務(wù)流程,建立領(lǐng)域模型,劃分邊界。

DDD事件風(fēng)暴四部曲?

  1. 識(shí)別領(lǐng)域事件

事件是對(duì)結(jié)果進(jìn)行建模,我們?cè)趯ふ翌I(lǐng)域事件時(shí),首先需要明白領(lǐng)域事件具備的幾個(gè)特征:

  • 具有業(yè)務(wù)意義
  • 過去時(shí),e.g: "XX已XX"
  • 時(shí)序性

事件風(fēng)暴以過去發(fā)生的事件追溯系統(tǒng)的數(shù)據(jù)和行為,從而進(jìn)行合適的建模,e.g:

事件風(fēng)暴.png
  1. 識(shí)別命令
    命令可以理解為不同角色用戶在界面上面的操作,比如“添加商品”,“編輯庫(kù)存”,“提交訂單”等; 有些命令可能產(chǎn)生多個(gè)事件,可以將他們用箭頭聯(lián)系起來; 在進(jìn)行這個(gè)過程中,我們也需要將角色,通過不同的顏色標(biāo)示出來 e.g:

    命令風(fēng)暴.png

  2. 尋找聚合
    在DDD中,聚合是一組相關(guān)的領(lǐng)域?qū)ο?,其目的是要確保業(yè)務(wù)規(guī)則在邊界內(nèi)的不變性,聚合根具有全局標(biāo)識(shí),所有對(duì)聚合根內(nèi)對(duì)象的修改,都只能通過聚合根進(jìn)行,聚合幫助我們簡(jiǎn)化了復(fù)雜的對(duì)象網(wǎng)絡(luò),逐步做到“高內(nèi)聚,低耦合”。
    在識(shí)別聚合的時(shí)候,我們可以通過對(duì)命令和事件的劃分找到聚合邊界,識(shí)別出分布在時(shí)間軸上面不同位置的相關(guān)命令和事件,e.g:

    尋找聚合.png

  3. 邊界劃分
    劃分服務(wù)的邊界,它一定程度上面對(duì)應(yīng)的是“界限上下文”,關(guān)于它有一個(gè)非常形象的定義:

細(xì)胞之所以會(huì)存在,是因?yàn)榧?xì)胞膜定義了什么在細(xì)胞內(nèi),什么在細(xì)胞外,并且確定了什么物質(zhì)可以通過細(xì)胞膜

一個(gè)聚合可能是最小顆粒度的界限上下文,同時(shí),我們常合并業(yè)務(wù)相關(guān)性很高的聚合。e.g:


界限上下文.png

最后在領(lǐng)域劃分的時(shí)候,需要團(tuán)隊(duì)一起對(duì)業(yè)務(wù)達(dá)成共識(shí),首先建立統(tǒng)一語言,然后識(shí)別領(lǐng)域模型,劃分子域和界限上下文,在驗(yàn)證界限上下文的時(shí)候,如果你發(fā)現(xiàn)有過多的角色在同一個(gè)子域或者界限上下文時(shí),就需要注意了,這就是典型的壞味道,需要及時(shí)調(diào)整的訊號(hào)。

DDD與微服務(wù)

理想情況下,界限上下文與微服務(wù)可以一一對(duì)應(yīng),在實(shí)際項(xiàng)目中,有些調(diào)整,比如根據(jù)業(yè)務(wù)的相關(guān)度和變化頻率,有時(shí)候我們會(huì)將多個(gè)界限上下文進(jìn)行合并;另外微服務(wù)在開發(fā),測(cè)試,部署,發(fā)布和運(yùn)維等等時(shí),相比單體應(yīng)用而言,它面臨了所有分布式系統(tǒng)面臨的問題,帶來了額外的復(fù)雜度和開銷,所以將微服務(wù)粒度拆分過細(xì)反而是一種反模式,需要考慮需要解決問題的復(fù)雜度,將相對(duì)簡(jiǎn)單的服務(wù)合并在一起;在微服務(wù)拆分的時(shí)候,也要注意:“聚合是服務(wù)的最小單元”(一個(gè)界限上下文可以包括多個(gè)聚合),打破聚合,就很有可能破壞事務(wù)一致性和業(yè)務(wù)約束。

參考資料

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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