為什么需要DDD?
我們經(jīng)常講技術(shù)為業(yè)務(wù)服務(wù),架構(gòu)設(shè)計(jì)需要對(duì)業(yè)務(wù)充分理解,在面向復(fù)雜的業(yè)務(wù)場(chǎng)景時(shí),會(huì)面臨諸多問(wèn)題:
- 復(fù)雜系統(tǒng)設(shè)計(jì):業(yè)務(wù)系統(tǒng)多、業(yè)務(wù)類型多、業(yè)務(wù)相互耦合,有沒(méi)有合適的方法來(lái)指導(dǎo)模塊的邊界開(kāi)發(fā)?
- 多團(tuán)隊(duì)協(xié)同:業(yè)務(wù)系統(tǒng)邊界劃分不清,系統(tǒng)間依賴復(fù)雜,往往一個(gè)邊界的理解就要扯半天,有沒(méi)有統(tǒng)一的語(yǔ)言來(lái)進(jìn)行建模,讓業(yè)務(wù)同學(xué)和技術(shù)同學(xué)都看得懂并理解一致?
- 設(shè)計(jì)和實(shí)現(xiàn)耦合:缺少設(shè)計(jì)文檔,業(yè)務(wù)及功能性代碼混雜,有時(shí)業(yè)務(wù)代碼可能不到10%,有沒(méi)有什么方法可以講業(yè)務(wù)需求準(zhǔn)確轉(zhuǎn)換為軟件設(shè)計(jì),有些代碼進(jìn)行有效的聚合,達(dá)到業(yè)務(wù)和技術(shù)的平衡?
- 缺乏靈活擴(kuò)展:針對(duì)頻繁變化的業(yè)務(wù),有沒(méi)有什么方法可以有效支持模型和服務(wù)如何支持場(chǎng)景的靈活擴(kuò)展?特別是商業(yè)環(huán)境、商業(yè)流程和規(guī)則多變,同時(shí)變化不可預(yù)測(cè),對(duì)架構(gòu)帶來(lái)很大挑戰(zhàn)
- 微服務(wù)拆分:怎么確定服務(wù)的業(yè)務(wù)邊界和應(yīng)用邊界?微服務(wù)的拆分粒度應(yīng)該多大,怎么拆分設(shè)計(jì)才算合理?
- 中臺(tái)規(guī)劃:如何能夠清晰的識(shí)別和發(fā)現(xiàn)業(yè)務(wù)模型中的共享和聯(lián)通部分,定義出哪些共享能力中心?
DDD的價(jià)值
- 統(tǒng)一語(yǔ)言:團(tuán)隊(duì)成員會(huì)在有界的上下文中有意識(shí)的形成統(tǒng)一語(yǔ)言,便于溝通,減少分歧
- 業(yè)務(wù)領(lǐng)域知識(shí)沉淀:業(yè)務(wù)通過(guò)核心穩(wěn)定的領(lǐng)域模型,領(lǐng)域知識(shí)進(jìn)行傳遞,業(yè)務(wù)相應(yīng)能力提升
- 邊界清晰的設(shè)計(jì)方法:用領(lǐng)域模型劃分出的邊界,來(lái)界定那些需求是合理的,哪些需求應(yīng)該在什么地方實(shí)現(xiàn),不斷拉齊團(tuán)隊(duì)內(nèi)成員對(duì)需求的認(rèn)知,讓設(shè)計(jì)更加清晰和規(guī)范,分而治之,控制規(guī)模
- 關(guān)注點(diǎn)分離:領(lǐng)域模型與數(shù)據(jù)模型分離,業(yè)務(wù)復(fù)雜度與技術(shù)復(fù)雜度分離,保持結(jié)構(gòu)清晰,應(yīng)對(duì)不可預(yù)測(cè)性挑戰(zhàn)
DDD核心切入點(diǎn)
DDD中比較關(guān)鍵的幾個(gè)切入點(diǎn)是通用語(yǔ)言、領(lǐng)域、限界上下文
通用語(yǔ)言 Ubiquitous Language
通用語(yǔ)言解決在業(yè)務(wù)人員和技術(shù)人員協(xié)作過(guò)程中非常重要的問(wèn)題,即團(tuán)隊(duì)所有人怎么講同一種語(yǔ)言?通用語(yǔ)言是提煉領(lǐng)域知識(shí)的產(chǎn)出物,獲得統(tǒng)一語(yǔ)言就是需求分析的過(guò)程,也是理解領(lǐng)域知識(shí)的過(guò)程。團(tuán)隊(duì)中各個(gè)角色就系統(tǒng)目標(biāo)、范圍與具體功能達(dá)成一致的過(guò)程。在實(shí)際過(guò)程中,可能由團(tuán)隊(duì)所有相關(guān)角色參加,比如領(lǐng)域?qū)<摇a(chǎn)品經(jīng)理、業(yè)務(wù)架構(gòu)師、技術(shù)架構(gòu)師、開(kāi)發(fā)人員。
通用語(yǔ)言可以定義公共術(shù)語(yǔ),減少概念混淆,消除歧義和理解偏差,提升需求和知識(shí)消化的效率;達(dá)到概念和代碼的統(tǒng)一語(yǔ)言,連接概念和實(shí)現(xiàn)。通用語(yǔ)言也需要行業(yè)參考,如果有一些領(lǐng)域模型有通用知識(shí)參考,則可簡(jiǎn)化通用語(yǔ)言的過(guò)程。
領(lǐng)域 Domain
領(lǐng)域是來(lái)確定范圍和邊界的,DDD將業(yè)務(wù)上的問(wèn)題將其限定歸屬在特定的邊界內(nèi),而這劃分出來(lái)的一個(gè)個(gè)邊界就可以叫做領(lǐng)域。為了降低業(yè)務(wù)理解和系統(tǒng)實(shí)現(xiàn)的復(fù)雜度,DDD會(huì)將領(lǐng)域進(jìn)一步劃分成更小力度的小問(wèn)題,也就是子域,子域根據(jù)自身重要性和功能屬性又可以劃分為三類子域:
核心域:決定產(chǎn)品和系統(tǒng)核心競(jìng)爭(zhēng)力的子域是核心域,它是影響產(chǎn)品和業(yè)務(wù)成功的主要因素,比如電商系統(tǒng)中關(guān)注的會(huì)員、商品、訂單、交易、庫(kù)存、營(yíng)銷等
通用域:沒(méi)有太多個(gè)性化的訴求,同時(shí)被多個(gè)子域使用的通用功能子域是通用域,比如統(tǒng)一的認(rèn)證和權(quán)限管理系統(tǒng)
支撐域:不包含決定產(chǎn)品和公司核心競(jìng)爭(zhēng)力的功能,也不包含通用功能的子域,但該功能子域又是產(chǎn)品所必須的,它就是支撐域。比如某個(gè)特定領(lǐng)域的數(shù)據(jù)字典。
限界上下文 Bounded Context
我們?cè)谄綍r(shí)溝通中為了避免同樣的詞語(yǔ)產(chǎn)生歧義,我們會(huì)把這個(gè)詞語(yǔ)帶入到語(yǔ)言上下文中去理解其語(yǔ)義。比如談到“蘋(píng)果”,有人可能想到平時(shí)吃的水果,有人也可能想到蘋(píng)果手機(jī)。
限界上下文是一個(gè)顯式的概念性邊界,領(lǐng)域模型都存在于這個(gè)邊界之內(nèi),出了這個(gè)邊界就不能確保這個(gè)含義。而上面提到的通用語(yǔ)言必須限制在這個(gè)限界上下文之中。在微服務(wù)設(shè)計(jì)中,一般一個(gè)限界上下文理論上就可以設(shè)計(jì)為一個(gè)微服務(wù)。
那么有了邊界后,我們?nèi)绾巫龅筋I(lǐng)域之間的交互呢?我們通過(guò)上下文映射的方式,一般方法有通過(guò)合作關(guān)系(一榮俱榮,一損俱損)、防腐層(通過(guò)一些適配和轉(zhuǎn)換)、共享內(nèi)核(依賴部分共享的模型)、依賴關(guān)系(有組織的上下游依賴)等,其中需要特別關(guān)注防腐層,強(qiáng)調(diào)單獨(dú)一層完成上下游的交互,隔離業(yè)務(wù)邏輯,在實(shí)際過(guò)程中會(huì)比較實(shí)用,比如在商品和采購(gòu)子域提供防腐層,將商品的變更進(jìn)行收口,隔離后端業(yè)務(wù)實(shí)現(xiàn)。
DDD核心結(jié)構(gòu)概念
實(shí)體 Entities
實(shí)體是一個(gè)具有唯一身份標(biāo)識(shí)的對(duì)象,并且可以在相當(dāng)長(zhǎng)的一段時(shí)間內(nèi)持續(xù)地變化。我們可以對(duì)實(shí)體做多次修改,一個(gè)實(shí)體對(duì)象可能和它先前的對(duì)象大不相同,但擁有相同的身份標(biāo)識(shí)(identity),依然是同一個(gè)實(shí)體。對(duì)這些對(duì)象而言,重要的不是其屬性,而是其延續(xù)性和標(biāo)識(shí),我們把這樣的對(duì)象稱為實(shí)體。
另外,實(shí)體具有可變性,這里需要引出兩個(gè)概念,貧血模型還是充血模型。貧血模型類似我們熟悉的Bean或者DO對(duì)象,一般只有g(shù)etter和setter方法,只作為保存狀態(tài)或者傳遞狀態(tài),但并不包含業(yè)務(wù)邏輯,這種只有數(shù)據(jù)沒(méi)有行為的對(duì)象不是真正的領(lǐng)域?qū)ο螅?DDD中的實(shí)體屬于充血模型,會(huì)封裝包含這個(gè)實(shí)體相關(guān)的所有業(yè)務(wù)邏輯,它不僅是多個(gè)業(yè)務(wù)屬性的載體,也是操作或行為的載體。
值對(duì)象 Value Object
值對(duì)象用來(lái)描述領(lǐng)域的特定方面,并且是一個(gè)沒(méi)有標(biāo)識(shí)符的對(duì)象。值對(duì)象本質(zhì)上就是一個(gè)集合,這個(gè)集合中包含若干個(gè)用于描述目的、具有整體概念和不可修改的屬性。它可以避免屬性零碎,讓屬性歸類更加地清晰,從概念理解上也更加完整。
值對(duì)象與實(shí)體的區(qū)別在于:值對(duì)象一般依附于實(shí)體而存在, 是實(shí)體屬性的一部分,而非獨(dú)立存在。值對(duì)象沒(méi)有唯一標(biāo)識(shí),當(dāng)任何屬性發(fā)生變化時(shí), 都意味著新的值對(duì)象產(chǎn)生。值對(duì)象功能單一,一般是貧血模型。
聚合 Aggregates
聚合是可以被視為?一組單個(gè)領(lǐng)域?qū)ο蟮募?,聚合由根?shí)體,值對(duì)象和實(shí)體組成,作為一個(gè)整體被外界訪問(wèn),。比如一個(gè)包含多條記錄的訂單,每條記錄都是單獨(dú)的對(duì)象,但訂單(連同所有記錄)一起視為單個(gè)聚合是有用的(封裝業(yè)務(wù)規(guī)則)。
聚合通過(guò)定義清晰的所屬關(guān)系和邊界,并避免錯(cuò)綜復(fù)雜的對(duì)象關(guān)系?網(wǎng)來(lái)實(shí)現(xiàn)模型的內(nèi)聚。在聚合邊界內(nèi),對(duì)象之間可以相互引用。聚合之間,聚合根是聚合中唯一允許被外部引用的元素,比如訂單ID。
領(lǐng)域服務(wù) Services
領(lǐng)域中的一些概念不太適合建模為對(duì)象,即歸類到實(shí)體對(duì)象或值對(duì)象,因?yàn)樗鼈儽举|(zhì)上就是一些操作,一些動(dòng)作。它們代表了領(lǐng)域中的一個(gè)重要的行為,所以不能忽略它們或者簡(jiǎn)單地把它們合并到某個(gè)實(shí)體或者值對(duì)象中。這些操作或動(dòng)作往往會(huì)涉及到多個(gè)領(lǐng)域?qū)ο螅⑶倚枰獏f(xié)調(diào)這些領(lǐng)域?qū)ο蠊餐瓿蛇@個(gè)操作或動(dòng)作。領(lǐng)域服務(wù)還有一個(gè)很重要的功能就是可以避免領(lǐng)域邏輯泄露到應(yīng)用層。因?yàn)槿绻麤](méi)有領(lǐng)域服務(wù),那么應(yīng)用層會(huì)直接調(diào)用領(lǐng)域?qū)ο笸瓿杀驹撌菍儆陬I(lǐng)域服務(wù)該做的操作。
識(shí)別領(lǐng)域服務(wù),主要看它是否滿足如下特點(diǎn):服務(wù)執(zhí)行的操作代表了一個(gè)領(lǐng)域概念,這個(gè)領(lǐng)域概念無(wú)法自然地隸屬于一個(gè)實(shí)體或者值對(duì)象;被執(zhí)行的操作涉及領(lǐng)域中的其他對(duì)象;操作是無(wú)狀態(tài)的。
領(lǐng)域建模常用方法
todo 實(shí)際項(xiàng)目分析補(bǔ)充
用例分析法
用例分析是比較通用的領(lǐng)域建模方法,可以在比較傳統(tǒng)需求調(diào)研過(guò)程中再結(jié)合領(lǐng)域模型的設(shè)計(jì)思路進(jìn)行,核心是通過(guò)通過(guò)需求、場(chǎng)景、規(guī)則、流程等梳理用例,進(jìn)而規(guī)劃領(lǐng)域模型。
首先,用例分析的基礎(chǔ)是做好需求調(diào)研,大致的步驟如下:
- 梳理領(lǐng)域概念:梳理出領(lǐng)域內(nèi)我們關(guān)注的概念、用力的關(guān)系,并統(tǒng)一交流詞匯,形成統(tǒng)一語(yǔ)言;
- 梳理業(yè)務(wù)規(guī)則:梳理出領(lǐng)域內(nèi)我們關(guān)注的各種業(yè)務(wù)規(guī)則,DDD中叫不變性(invariants),比如唯一性規(guī)則、促銷互斥疊加等;
- 梳理業(yè)務(wù)場(chǎng)景:梳理出領(lǐng)域內(nèi)的核心業(yè)務(wù)場(chǎng)景,比如電商領(lǐng)域的訂單尋源、庫(kù)存鎖定、商品價(jià)格計(jì)算等、優(yōu)惠券核銷等業(yè)務(wù)場(chǎng)景;
- 梳理業(yè)務(wù)流程:梳理出領(lǐng)域內(nèi)的關(guān)鍵業(yè)務(wù)流程,比如訂單處理流程,分單拆單邏輯,逆向退款邏輯等
用例整理好后,可以根據(jù)語(yǔ)義來(lái)整理用例,進(jìn)而整理領(lǐng)域模型,大概步驟如下:
- 收集用例:從領(lǐng)域、規(guī)則、場(chǎng)景、流程中進(jìn)行提取,收集相應(yīng)的名詞、動(dòng)詞、形容詞
- 提取實(shí)體:從名詞中定位出主要實(shí)體,比如商品、SKU、品類等
- 提取屬性:從形容詞中添加實(shí)體屬性,比如顏色、價(jià)格等
- 添加關(guān)聯(lián):動(dòng)詞添加實(shí)體和實(shí)體之間的關(guān)聯(lián),比如商品“包含”SKU,賣家“開(kāi)設(shè)”店鋪等
- 完善模型:識(shí)別出初步模型,驗(yàn)證并迭代模型,同時(shí)補(bǔ)充用例驗(yàn)證模型、業(yè)務(wù)流程驗(yàn)證模型
四色建模法
四色建模在實(shí)際中也比較常用,有幾個(gè)核心概念:
時(shí)間(Moment-Interval):具有可追溯性的記錄運(yùn)營(yíng)或管理數(shù)據(jù)的時(shí)刻或時(shí)段對(duì)象,用粉紅色表示
人貨場(chǎng)(Party-Place-Thing Archetype):也叫PPT,代表參與到流程中的參與方/地點(diǎn)/物,用綠色表示
角色(Role):在時(shí)標(biāo)型對(duì)象與 PPT 對(duì)象(通常是參與方)之間參與的角色,用黃色表示
描述(Description):對(duì) PPT 對(duì)象的一種補(bǔ)充描述,用藍(lán)色表示
簡(jiǎn)單說(shuō),四色法關(guān)注的是,某個(gè)人(Party)的角色(PartyRole)在某個(gè)地點(diǎn)(Place)的角色(PlaceRole)用某個(gè)東西(Thing)的角色(ThingRole)做了某件事情(MomentInterval)
事件風(fēng)暴法
事件風(fēng)暴也稱為事件建模,類似頭腦風(fēng)暴,可以快速分析復(fù)雜業(yè)務(wù)領(lǐng)域,完成領(lǐng)域建模的目標(biāo)。關(guān)注如下元素:
事件 -> 某個(gè)動(dòng)作的結(jié)果
屬性-> 事件的輸入、輸出
命令-> 某個(gè)動(dòng)作
實(shí)體-> 命令的觸發(fā)者
簡(jiǎn)單理解就是誰(shuí)(實(shí)體)在何時(shí)(時(shí)間)基于什么(輸入)做了什么(命令、動(dòng)作)產(chǎn)生了什么(輸出)影響了什么(事件)。
事件風(fēng)暴強(qiáng)調(diào)正確的人(業(yè)務(wù)?員,領(lǐng)域?qū)<?,技術(shù)?員,架構(gòu)師,測(cè)試?員等關(guān)鍵?色都要參與其中),開(kāi)放空間(有足夠的空間可以將事件流可視化,讓?們可以交互討論),即時(shí)貼(至少三種顏色),關(guān)聯(lián)的人充分討論,集體決策,從價(jià)值角度來(lái)審視業(yè)務(wù)流程的合理性,領(lǐng)域事件容易創(chuàng)建業(yè)務(wù)人員和非業(yè)務(wù)人員的共識(shí)。
DDD分層架構(gòu)
展現(xiàn)層:它負(fù)責(zé)向前臺(tái)顯示信息和解釋用戶命令,完成前端界面邏輯。展示層的組件實(shí)現(xiàn)用戶與應(yīng)用交互的功能。一般建議用MVC,MVP或者M(jìn)VVM模式來(lái)分隔這些組件為子層。
應(yīng)用層:它是很薄的一層,負(fù)責(zé)展現(xiàn)層與領(lǐng)域?qū)又g的協(xié)調(diào),也是與其它系統(tǒng)應(yīng)用層進(jìn)行交互的必要渠道,例如事務(wù)、執(zhí)行單位操作、調(diào)用應(yīng)用程序的任務(wù)。應(yīng)用層要盡量簡(jiǎn)單,不包含業(yè)務(wù)規(guī)則或者知識(shí),不保留業(yè)務(wù)對(duì)象的狀態(tài),只保留有應(yīng)用任務(wù)的進(jìn)度狀態(tài),更注重流程性的東西。它只為領(lǐng)域?qū)又械念I(lǐng)域?qū)ο髤f(xié)調(diào)任務(wù),分配工作,使它們互相協(xié)作。類似于Fa?ade模式,調(diào)用領(lǐng)域?qū)雍突A(chǔ)設(shè)施層來(lái)完成應(yīng)用的用例。
領(lǐng)域?qū)?/strong>:它是業(yè)務(wù)軟件的核心所在,包含了前面提到的核心概念,如領(lǐng)域?qū)ο螅▽?shí)體、值對(duì)象)、領(lǐng)域服務(wù)以及它們之間的關(guān)系,負(fù)責(zé)表達(dá)業(yè)務(wù)概念、業(yè)務(wù)狀態(tài)信息以及業(yè)務(wù)規(guī)則,具體表現(xiàn)形式就是領(lǐng)域模型。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)提倡充血模型,即盡量將業(yè)務(wù)邏輯歸屬到領(lǐng)域?qū)ο笊稀?br>基礎(chǔ)設(shè)施層:它向其他層提供通用的技術(shù)能力,為應(yīng)用層傳遞消息(API 網(wǎng)關(guān)等),為領(lǐng)域?qū)犹峁┏志没瘷C(jī)制(如數(shù)據(jù)庫(kù)資源、中間件交互、緩存、MQ消息)等,屏蔽技術(shù)底座能力(如底層服務(wù)的健康度檢查、配置參數(shù)等)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-484956.html
DDD與傳統(tǒng)設(shè)計(jì)方式不同
DDD給我們帶來(lái)的是設(shè)計(jì)模式的改變。DDD的設(shè)計(jì)模式與傳統(tǒng)的面向數(shù)據(jù)驅(qū)動(dòng)的開(kāi)發(fā)模式有顯出區(qū)別,這一點(diǎn)特別需要技術(shù)同學(xué)在具體操作時(shí)關(guān)注。數(shù)據(jù)驅(qū)動(dòng)是從數(shù)據(jù)出發(fā),先梳理ER圖,設(shè)計(jì)數(shù)據(jù)庫(kù)表,編寫(xiě)DAO,然后進(jìn)行業(yè)務(wù)實(shí)現(xiàn)。而領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)從領(lǐng)域出發(fā),分析領(lǐng)域內(nèi)模型及其關(guān)系,并進(jìn)行領(lǐng)域建模,設(shè)計(jì)核心業(yè)務(wù)邏輯,進(jìn)而再進(jìn)行技術(shù)細(xì)節(jié)實(shí)現(xiàn)。其核心思想是通過(guò)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)方法定義領(lǐng)域模型,從而確定業(yè)務(wù)和應(yīng)用邊界,保證業(yè)務(wù)模型與代碼模型的一致性。在DDD中,領(lǐng)域模型和數(shù)據(jù)模型是解耦的,有時(shí)也不是一一對(duì)應(yīng),因此,如果一開(kāi)始應(yīng)用DDD進(jìn)行設(shè)計(jì)時(shí),一定要跳出數(shù)據(jù)模型優(yōu)先的束縛,不要讓領(lǐng)域模型被數(shù)據(jù)模型綁架,先設(shè)計(jì)出合理的領(lǐng)域模型是首要任務(wù)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-484956.html
到了這里,關(guān)于DDD領(lǐng)域驅(qū)動(dòng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!