您好,登錄后才能下訂單哦!
這篇文章主要講解了“DDD建模六個問題與步驟是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“DDD建模六個問題與步驟是什么”吧!
DDD方法論的核心是將問題不斷分解,把大問題分解為小問題,大業(yè)務(wù)分解小領(lǐng)域,簡而言之就是分而治之,各個擊破。
分而治之是指直接面對大業(yè)務(wù)我們無從下手,需要按照一定方法進行分解,分解為高內(nèi)聚的小領(lǐng)域,使得業(yè)務(wù)有邊界清晰,而這些小領(lǐng)域是我們有能力處理的,這就是領(lǐng)域驅(qū)動設(shè)計的核心。
各個擊破是指當(dāng)問題被拆分為小領(lǐng)域后,因為小領(lǐng)域業(yè)務(wù)內(nèi)聚,其子領(lǐng)域高度相關(guān),我們在技術(shù)維度可以對其進行詳細(xì)設(shè)計,在管理維度可以按照領(lǐng)域?qū)椖窟M行分工。需要指出DDD不能替代詳細(xì)設(shè)計,DDD是為了更清晰地進詳細(xì)設(shè)計。
在微服務(wù)流行的互聯(lián)網(wǎng)行業(yè),當(dāng)業(yè)務(wù)逐漸復(fù)雜時,技術(shù)人員需要解決如何劃分微服務(wù)邊界的問題,DDD這種清晰化業(yè)務(wù)邊界的特性正好可以用來解決這個問題。
我們的目標(biāo)是將業(yè)務(wù)劃分清晰的邊界,而DDD是達(dá)成目標(biāo)的有效方法之一,這一點是需要格外注意的。DDD是方法不是目標(biāo),不需要為了使用而使用。例如業(yè)務(wù)模型比較簡單可以很容易分析的業(yè)務(wù)就不需要使用DDD,還有一些目標(biāo)是快速驗證類型的項目,追求短平快,前期可能也不需要使用領(lǐng)域驅(qū)動設(shè)計。
領(lǐng)域可以劃分多個子領(lǐng)域,子域可以再劃分多個子子域,限界上下文本質(zhì)上也是一種子子域,那么在業(yè)務(wù)分解時一個業(yè)務(wù)模塊到底是領(lǐng)域、子域還是子子域?
我認(rèn)為不用糾結(jié)在這個問題,因為這取決于看待這個模塊的角度。你認(rèn)為整體可能是別人的局部,你認(rèn)為的局部可能是別人的整體,叫什么名字不重要,最重要的是按照高內(nèi)聚的原則將業(yè)務(wù)高度相關(guān)的模塊收斂在一起。
業(yè)務(wù)劃分粒度的粗細(xì)并沒有統(tǒng)一的標(biāo)準(zhǔn),還是要根據(jù)業(yè)務(wù)需要、開發(fā)資源、技術(shù)實力等因素綜合考量。例如微服務(wù)拆分過細(xì)反而會增加開發(fā)、部署和維護的復(fù)雜度,但是拆分過粗可能會導(dǎo)致大量業(yè)務(wù)高度耦合,開發(fā)部署起來是挺快的,但是缺失可維護性和可擴展性,這需要根據(jù)實際情況做出權(quán)衡。
領(lǐng)域?qū)ο笈c數(shù)據(jù)對象一個重要的區(qū)別是值對象存儲方式。在討論領(lǐng)域?qū)ο蠛蛿?shù)據(jù)對象之前,我們首先討論實體和值對象這一組概念。實體是具有唯一標(biāo)識的對象,而唯一標(biāo)識會伴隨實體對象整個生命周期并且不可變更。值對象本質(zhì)上是屬性的集合,并沒有唯一標(biāo)識。
領(lǐng)域?qū)ο笤诎祵ο蟮耐瑫r也保留了值對象的業(yè)務(wù)含義,而數(shù)據(jù)對象可以使用更加松散的結(jié)構(gòu)保存值對象,簡化數(shù)據(jù)庫設(shè)計。
現(xiàn)在假設(shè)我們需要管理足球運動員信息,對應(yīng)的領(lǐng)域模型和數(shù)據(jù)模型應(yīng)該如何設(shè)計?姓名、身高、體重是一名運動員本質(zhì)屬性,加上唯一編號可以對應(yīng)實體對象。跑動距離,傳球成功率,進球數(shù)是運動員比賽中的表現(xiàn),這些屬性的集合可以對應(yīng)值對象。
值對象在數(shù)據(jù)對象中可以用松散的數(shù)據(jù)結(jié)構(gòu)進行存儲,而值對象在領(lǐng)域?qū)ο笾行枰A羝錁I(yè)務(wù)含義如下圖所示:
我們根據(jù)圖示編寫領(lǐng)域?qū)ο笈c數(shù)據(jù)對象代碼:
// 數(shù)據(jù)對象
public class FootballPlayerDO {
private Long id;
private String name;
private Integer height;
private Integer weight;
private String gamePerformance;
}
// 領(lǐng)域?qū)ο?br/>public class FootballPlayerDMO {
private Long id;
private String name;
private Integer height;
private Integer weight;
private GamePerformanceVO gamePerformanceVO;
}
public class GamePerformanceVO {
private Double runDistance;
private Double passSuccess;
private Integer scoreNum;
}
抽象的核心是找相同,對不同事物提取公因式。實現(xiàn)的核心是找不同,擴展各自的屬性和特點。例如模板方法設(shè)計模式正是用抽象構(gòu)建框架,用實現(xiàn)擴展細(xì)節(jié)。
我們再回到數(shù)據(jù)模型的討論,可以發(fā)現(xiàn)腳本化是一種拓展靈活性的方式,腳本化不僅指使用groovy、QLExpress腳本增強系統(tǒng)靈活性,還包括松散可擴展的數(shù)據(jù)結(jié)構(gòu)。數(shù)據(jù)模型抽象出了姓名、身高、體重這些基本屬性,對于頻繁變化的比賽表現(xiàn)屬性,這些屬性值可能經(jīng)常變化,甚至屬性本身也是經(jīng)常變化,例如可能會加上射門次數(shù),突破次數(shù)等,所以采用松散的JSON數(shù)據(jù)結(jié)構(gòu)進行存儲。
工程理論總是要落地的,落地也是需要一些步驟和方法的。本文我們一起分析一個足球運動員信息管理系統(tǒng),目標(biāo)是管理運動員從轉(zhuǎn)會到上場比賽整條鏈路信息,這個系統(tǒng)大家應(yīng)該也都沒有接觸過,我們一起來分析。需要說明本實例著重演示DDD方法論如何落地,業(yè)務(wù)細(xì)節(jié)可能并不能面面俱到。
梳理流程有兩個問題需要考慮,第一個問題是從什么視角去梳理?因為不同的人看到的流程是不一樣的。答案是取決于系統(tǒng)需要解決的是什么問題,因為我們要管理運動員從轉(zhuǎn)會到上場比賽整條鏈路信息,所以從運動員視角出發(fā)是一個合適的選擇。
第二個問題是對業(yè)務(wù)不熟悉怎么辦?因為我們不是體育和運動專家,并不清楚整條鏈路的業(yè)務(wù)細(xì)節(jié)。答案是梳理流程時一定要有業(yè)務(wù)專家在場,因為沒有真實業(yè)務(wù)細(xì)節(jié),無法領(lǐng)域驅(qū)動設(shè)計。同理在互聯(lián)網(wǎng)梳理復(fù)雜業(yè)務(wù)流程時,一定要有對相關(guān)業(yè)務(wù)熟悉的產(chǎn)品經(jīng)理或者運營一起參與。
假設(shè)足球業(yè)務(wù)專家梳理出了業(yè)務(wù)流程,運動員提出轉(zhuǎn)會,協(xié)商一致后到新俱樂部體檢,體檢通過就進行簽約。進入新俱樂部后進行訓(xùn)練,訓(xùn)練指標(biāo)達(dá)標(biāo)后上場比賽,賽后參加新聞發(fā)布會。
四色建模第一種顏色是紅色,表示時標(biāo)對象。時標(biāo)對象是四色建模最重要的對象,可以理解為核心業(yè)務(wù)單據(jù)。在業(yè)務(wù)進行過程中一定要對關(guān)鍵業(yè)務(wù)留下單據(jù),通過這些單據(jù)可以追溯出整個業(yè)務(wù)流程。
時標(biāo)對象具有兩個特點:第一是事實不可變性,記錄了過去某個時間點或時間段內(nèi)發(fā)生的事實。第二是責(zé)任可追溯性,記錄了管理者關(guān)注的信息?,F(xiàn)在我們分析本系統(tǒng)時標(biāo)對象有哪些,需要留下哪些核心業(yè)務(wù)單據(jù)。
轉(zhuǎn)會對應(yīng)轉(zhuǎn)會單據(jù),體檢對應(yīng)體檢單據(jù),簽合同對應(yīng)合同單據(jù),訓(xùn)練對應(yīng)訓(xùn)練指標(biāo)單據(jù),比賽對應(yīng)比賽指標(biāo)單據(jù),新聞發(fā)布會對應(yīng)采訪單據(jù)。根據(jù)分析繪制如下時標(biāo)對象:
這三類對象在四色建模中用綠色表示,我們以電商場景為例進行說明。用戶支付購買商家的商品時,用戶和商家是參與方。物流系統(tǒng)發(fā)貨時配送單據(jù)需要有配送地址對象,地址對象就是地。訂單需要商品對象,物流配送需要有貨品,商品和貨品就是物。
我們分析本例可以知道參與方包含總經(jīng)理、隊醫(yī)、教練、球迷、記者,地包含訓(xùn)練地址、比賽地址、采訪地址,物包含簽名球衣和簽名足球:
在四色建模中用黃色表示,這類對象表示參與方、地、物是以什么角色參與到業(yè)務(wù)流程:
我們可以為對象增加相關(guān)描述信息,在四色建模中用藍(lán)色表示:
在四色建模過程中我們體會到時標(biāo)對象是最重要的對象,因為其承載了業(yè)務(wù)系統(tǒng)核心單據(jù)。在劃分領(lǐng)域時我們同樣離不開時標(biāo)對象,通過收斂相關(guān)時標(biāo)對象劃分領(lǐng)域。
當(dāng)業(yè)務(wù)系統(tǒng)發(fā)生一件事情時,如果本領(lǐng)域或其它領(lǐng)域有后續(xù)動作跟進,那么我們把這件事情稱為領(lǐng)域事件,這個事件需要被感知。
例如球員比賽受傷了,這是比賽子域事件,但是醫(yī)療和訓(xùn)練子域是需要感知的,那么比賽子域就發(fā)出一個事件,醫(yī)療和訓(xùn)練子域會訂閱。
例如球員比賽取得進球,這也是比賽子域事件,但是訓(xùn)練和合同子域也會關(guān)注這個事件,所以比賽子域也會發(fā)出一個比賽進球事件,訓(xùn)練和合同子域會訂閱。
通過事件交互有一個問題需要注意,通過事件訂閱實現(xiàn)業(yè)務(wù)只能采用最終一致性,需要放棄強一致性,這一點可能會引入新的復(fù)雜度需要權(quán)衡。
接口層:提供面向外部接口聲明和DTO對象
訪問層:提供HTTP訪問入口
業(yè)務(wù)層:領(lǐng)域?qū)雍蜆I(yè)務(wù)層都包含業(yè)務(wù),但是用途不同。業(yè)務(wù)層可以組合不同領(lǐng)域業(yè)務(wù),并且可以增加流控、監(jiān)控、日志、權(quán)限控制切面,相較于領(lǐng)域?qū)痈鼮樨S富,提供BO對象
領(lǐng)域?qū)樱禾峁〥MO(DomainObject)、VO、事件、數(shù)據(jù)訪問對象,核心是按照領(lǐng)域進行分包,領(lǐng)域內(nèi)高內(nèi)聚,領(lǐng)域間低耦合
外部訪問層:在這個模塊中調(diào)用外部RPC服務(wù),解析返回碼和返回數(shù)據(jù)
基礎(chǔ)層:包含基礎(chǔ)功能,例如緩存工具,消息隊列,分布式鎖,消息發(fā)送等功能
我們展開領(lǐng)域?qū)舆M行分析。領(lǐng)域?qū)拥暮诵氖前凑疹I(lǐng)域進行分包,并且提供DMO、VO、事件、數(shù)據(jù)訪問對象,領(lǐng)域內(nèi)高內(nèi)聚,領(lǐng)域間低耦合,例如domain1對應(yīng)合同子域,domain2對應(yīng)訓(xùn)練子域,domain3對應(yīng)合同子域。
目前為止領(lǐng)域已經(jīng)確定了,現(xiàn)在可以根據(jù)領(lǐng)域劃分任務(wù)了,組內(nèi)成員分別負(fù)責(zé)一個或多個領(lǐng)域進行詳細(xì)設(shè)計,這個階段就是大家非常熟悉的用例圖,活動圖,時序圖,數(shù)據(jù)庫設(shè)計,接口設(shè)計的用武之地。需要說明的是領(lǐng)域驅(qū)動設(shè)計不是取代詳細(xì)設(shè)計,而是為了更清晰地詳細(xì)設(shè)計。
感謝各位的閱讀,以上就是“DDD建模六個問題與步驟是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對DDD建模六個問題與步驟是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。