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

淺談DDD,你學會了嗎?

開發(fā) 架構(gòu)
本文主要從DDD是什么,能干什么,不能干什么,怎么干(領(lǐng)域建模方法、實現(xiàn)方法論)幾個方面來聊了一下領(lǐng)域驅(qū)動,當然,一千個人有一千種對領(lǐng)域驅(qū)動的理解。?

?DDD 最近幾年越來越流行,大家都在聊這個話題,但是每個人對它的理解都不同,小汪哥這里根據(jù)之前在系統(tǒng)拆分、需求評估,以及遺留系統(tǒng)改造中的一點點經(jīng)驗,來淺淺的聊下自己對DDD的理解。從認知定義、作用、領(lǐng)域建模方法、實現(xiàn)方法論幾個方面來聊聊。

認知定義

DDD 是一種處理高度復(fù)雜領(lǐng)域的設(shè)計思想,它試圖分離技術(shù)實現(xiàn)的復(fù)雜性,并圍繞業(yè)務(wù)概念構(gòu)建領(lǐng)域模型來控制業(yè)務(wù)的復(fù)雜性,以解決軟件難以理解,難以演進的問題。

DDD 不是架構(gòu),而是一種架構(gòu)設(shè)計方法論,它通過邊界劃分將復(fù)雜業(yè)務(wù)領(lǐng)域簡單化,幫我們設(shè)計出清晰的領(lǐng)域和應(yīng)用邊界,可以很容易地實現(xiàn)架構(gòu)演進和微服務(wù)的落地。

作用

優(yōu)勢:

1、作為微服務(wù)的定義的指導(dǎo)思想。

2、理解業(yè)務(wù)的一種方法論,可以在接手遺留系統(tǒng),以及遺留系統(tǒng)改造時快速理解業(yè)務(wù)。

3、解決領(lǐng)域知識被割裂肢解、代碼的業(yè)務(wù)語義表達能力弱的問題。

4、控制系統(tǒng)復(fù)雜度,控制代碼量。

劣勢:

1、DDD不能解決大部分的性能優(yōu)化問題,甚至大部分的場景,我們需要為性能優(yōu)化去做反DDD設(shè)計。

2、DDD不能解決開發(fā)技術(shù)水平的問題。

3、DDD需要我們在領(lǐng)域建?;ㄙM很多的時間和精力,而且還可能導(dǎo)致付出和收益不成正比的情況。

領(lǐng)域建模方法

領(lǐng)域建模解決的問題

領(lǐng)域建模的目的是統(tǒng)一大家的業(yè)務(wù)認知,讓業(yè)務(wù)、開發(fā)、測試、產(chǎn)品在同一個頻道上交流。其實要做到這一點是很難的,開發(fā)喜歡從技術(shù)層面去描述問題,產(chǎn)品習慣從業(yè)務(wù)層面描述問題,兩個不在同一個頻道怎么能好好溝通。在小團隊這種優(yōu)勢表現(xiàn)不出來,在大團隊中,溝通成本是很高的。

領(lǐng)域建模,說的很簡單,但是做好確實很難,一個復(fù)雜的需求不是建幾個實體對象就能解決的。從全局看只在腦海中進行的建模實際上并不一定正確和穩(wěn)定。因此我們需要找到正確的方法幫助對業(yè)務(wù)領(lǐng)域進行分析,得到建模結(jié)構(gòu),共享建模成果。值得慶幸的是,前輩及牛人已經(jīng)總結(jié)了一些建模方法。

常用的建模方法有:用例分析法、四色建模法、事件風暴法。這個我就不一一贅述了,網(wǎng)上有很多內(nèi)容,或者公眾號回復(fù)【DDD】獲取相關(guān)資料。

實現(xiàn)方法論

戰(zhàn)略設(shè)計:

戰(zhàn)略設(shè)計主要從業(yè)務(wù)視角出發(fā),建立業(yè)務(wù)領(lǐng)域模型,劃分領(lǐng)域邊界,建立通用語言的限界上下文,限界上下文可以作為微服務(wù)設(shè)計的參考邊界。

各種域:

核心域、支撐域和通用域的主要目標是:通過領(lǐng)域劃分,區(qū)分不同子域在公司內(nèi)的不同功能屬性和重要性,從而公司可對不同子域采取不同的資源投入和建設(shè)策略,其關(guān)注度也會不一樣。

統(tǒng)一語言:

統(tǒng)一語言提供了一種更好的協(xié)同方式的可能性。統(tǒng)一語言與其背后的領(lǐng)域模型賦予了研發(fā)人員通過重構(gòu)定義業(yè)務(wù)的能力,在業(yè)務(wù)方大多強勢的環(huán)境中,難能可貴地建立了技術(shù)反饋業(yè)務(wù)的途徑,降低了知識消化過程失敗的風險。

圖片

圖片來源:《如何落地業(yè)務(wù)建?!?/p>

限界上下文:

限界上下文是微服務(wù)設(shè)計和拆分的主要依據(jù)。在領(lǐng)域模型中,如果不考慮技術(shù)異構(gòu)、團隊溝通等其它外部因素,一個限界上下文理論上就可以設(shè)計為一個微服務(wù)。

限界上下文的定義就是:用來封裝通用語言和領(lǐng)域?qū)ο?,提供上下文環(huán)境,保證在領(lǐng)域之內(nèi)的一些術(shù)語、業(yè)務(wù)相關(guān)對象等(通用語言)有一個確切的含義,沒有二義性。

正如電商領(lǐng)域的商品一樣,商品在不同的階段有不同的術(shù)語,在銷售階段是商品,而在運輸階段則變成了貨物。同樣的一個東西,由于業(yè)務(wù)領(lǐng)域的不同,賦予了這些術(shù)語不同的涵義和職責邊界,這個邊界就可能會成為未來微服務(wù)設(shè)計的邊界??吹竭@,領(lǐng)域邊界就是通過限界上下文來定義的。

戰(zhàn)術(shù)設(shè)計:

戰(zhàn)術(shù)設(shè)計則從技術(shù)視角出發(fā),側(cè)重于領(lǐng)域模型的技術(shù)實現(xiàn),完成軟件開發(fā)和架構(gòu)落地,包括:聚合根、實體、值對象等代碼邏輯及代碼分層的設(shè)計和實現(xiàn)。主要討論在一個服務(wù)內(nèi)部,如何劃分和組織代碼。

實體和值對象:

實體和值對象:從領(lǐng)域模型的基礎(chǔ)單元看系統(tǒng)設(shè)計實體和值對象是組成領(lǐng)域模型的基礎(chǔ)單元。

實體的代碼形態(tài)

在代碼模型中,實體的表現(xiàn)形式是實體類,這個類包含了實體的屬性和方法,通過這些方法實現(xiàn)實體自身的業(yè)務(wù)邏輯。在 DDD 里,這些實體類通常采用充血模型,與這個實體相關(guān)的所有業(yè)務(wù)邏輯都在實體類的方法中實現(xiàn),跨多個實體的領(lǐng)域邏輯則在領(lǐng)域服務(wù)中實現(xiàn)。

實體以 DO(領(lǐng)域?qū)ο螅┑男问酱嬖冢總€實體對象都有唯一的 ID。我們可以對一個實體對象進行多次修改,修改后的數(shù)據(jù)和原來的數(shù)據(jù)可能會大不相同。但是,由于它們擁有相同的 ID,它們依然是同一個實體。

實體的數(shù)據(jù)庫形態(tài)?

在領(lǐng)域模型映射到數(shù)據(jù)模型時,一個實體可能對應(yīng) 0 個、1 個或者多個數(shù)據(jù)庫持久化對象。大多數(shù)情況下實體與持久化對象是一對一。在某些場景中,有些實體只是暫駐靜態(tài)內(nèi)存的一個運行態(tài)實體,它不需要持久化。

值對象?

值對象相對實體來說,會更加抽象一些。簡單來說,值對象本質(zhì)上就是一個集合。

值對象的代碼形態(tài)?

值對象在代碼中有這樣兩種形態(tài)。如果值對象是單一屬性,則直接定義為實體類的屬性;如果值對象是屬性集合,則把它設(shè)計為 Class 類,Class 將具有整體概念的多個屬性歸集到屬性集合,這樣的值對象沒有 ID,會被實體整體引用。

圖片

圖片來源:《DDD 實戰(zhàn)課》

例如上圖:

人員實體原本包括:姓名、年齡、性別以及人員所在的省、市、縣和街道等屬性。這樣顯示地址相關(guān)的屬性就很零碎了對不對?現(xiàn)在,我們可以將“省、市、縣和街道等屬性”拿出來構(gòu)成一個“地址屬性集合”,這個集合就是值對象了。

聚合和聚合根:

領(lǐng)域模型內(nèi)的實體和值對象就好比個體,而能讓實體和值對象協(xié)同工作的組織就是聚合,它用來確保這些領(lǐng)域?qū)ο笤趯崿F(xiàn)共同的業(yè)務(wù)邏輯時,能保證數(shù)據(jù)的一致性。聚合就是由業(yè)務(wù)和邏輯緊密關(guān)聯(lián)的實體和值對象組合而成的,聚合是數(shù)據(jù)修改和持久化的基本單元,每一個聚合對應(yīng)一個倉儲,實現(xiàn)數(shù)據(jù)的持久化。聚合有一個聚合根和上下文邊界(一個聚合包含了多個實體對象和值對象,其中有一個實體對象做為聚合根。這些對象聚集在一起形成了一個比較完整獨立的業(yè)務(wù)邊界,稱為上下文邊界。),這個邊界根據(jù)業(yè)務(wù)單一職責和高內(nèi)聚原則,定義了聚合內(nèi)部應(yīng)該包含哪些實體和值對象,而聚合之間的邊界是松耦合的。按照這種方式設(shè)計出來的微服務(wù)很自然就是“高內(nèi)聚、低耦合”的。

我們以保險的投保業(yè)務(wù)場景為例,看一下聚合的構(gòu)建過程主要都包括哪些步驟:

圖片

圖片來源:《DDD 實戰(zhàn)課》

聚合根?

聚合根 leave 中有屬性、值對象、關(guān)聯(lián)實體和自身的業(yè)務(wù)行為。Leave 實體采用充血模型 ,有自己的業(yè)務(wù)行為,具體就是聚合根實體類的方法,如代碼中的 getDuration 和 addHistoryApprovalInfo 等方法。

聚合根引用實體和值對象,它可以組合聚合內(nèi)的多個實體,在聚合根實體類方法中完成復(fù)雜的業(yè)務(wù)行為,這種復(fù)雜的業(yè)務(wù)行為也可以在聚合領(lǐng)域服務(wù)里實現(xiàn)。但為了職責和邊界清晰,我建議聚合要根據(jù)自身的業(yè)務(wù)行為在實體類方法中實現(xiàn),而涉及多個實體組合才能實現(xiàn)的業(yè)務(wù)能力由領(lǐng)域服務(wù)完成。下面是聚合根 leave 的實體類方法,它包含屬性、對實體和值對象的引用以及自己的業(yè)務(wù)行為和方法。

public class Leave {    String id;    Applicant applicant;    Approver approver;    LeaveType type;    Status status;    Date startTime;    Date endTime;    long duration;    int leaderMaxLevel; //審批領(lǐng)導(dǎo)的最高級別    ApprovalInfo currentApprovalInfo;    List<ApprovalInfo> historyApprovalInfos; 
public long getDuration() return endTime.getTime() - startTime.getTime(); }
public Leave addHistoryApprovalInfo(ApprovalInfo approvalInfo) if (null == historyApprovalInfos) historyApprovalInfos = new ArrayList<>(); this.historyApprovalInfos.add(approvalInfo); return this; }
public Leave create(){ this.setStatus(Status.APPROVING); this.setStartTime(new Date()); return this;}
//其它方法}

DDD分層架構(gòu)

最后就是如何組織代碼的問題,這個時候就需要要到DDD的分層架構(gòu)。

那么從之前的MVC三層架構(gòu)如何演變成DDD的分層架構(gòu)呢? 

DDD分層架構(gòu)與MVC架構(gòu)的映射關(guān)系:

圖片

在《領(lǐng)域驅(qū)動設(shè)計——軟件核心復(fù)雜性應(yīng)對之道》書中也描述了各層的關(guān)系:

圖片

不過小汪哥覺得,代碼的組織方式可以根據(jù)團隊的情況來調(diào)整,只要能符合領(lǐng)域驅(qū)動的思想即可。

各個層級的作用可以參考之前的文章:領(lǐng)域驅(qū)動落地實戰(zhàn)?,這里就不在一一贅述了。

小結(jié)

本文主要從DDD是什么,能干什么,不能干什么,怎么干(領(lǐng)域建模方法、實現(xiàn)方法論)幾個方面來聊了一下領(lǐng)域驅(qū)動,當然,一千個人有一千種對領(lǐng)域驅(qū)動的理解。?

責任編輯:武曉燕 來源: 小汪哥寫代碼
相關(guān)推薦

2022-04-29 08:55:43

前端開發(fā)規(guī)范

2024-02-28 09:07:58

鏈路聚合模式

2023-01-13 16:46:38

CRM系統(tǒng)建設(shè)

2024-05-30 09:43:00

2024-02-04 00:00:00

Effect數(shù)據(jù)組件

2023-07-26 13:11:21

ChatGPT平臺工具

2024-01-19 08:25:38

死鎖Java通信

2024-01-02 12:05:26

Java并發(fā)編程

2023-08-01 12:51:18

WebGPT機器學習模型

2023-08-30 07:21:59

2022-06-16 07:50:35

數(shù)據(jù)結(jié)構(gòu)鏈表

2022-12-06 07:53:33

MySQL索引B+樹

2023-07-30 22:29:51

BDDMockitoAssert測試

2023-10-06 14:49:21

SentinelHystrixtimeout

2024-02-02 11:03:11

React數(shù)據(jù)Ref

2024-03-06 08:28:16

設(shè)計模式Java

2022-07-13 08:16:49

RocketMQRPC日志

2023-01-31 08:02:18

2023-03-26 22:31:29

2023-05-05 06:54:07

MySQL數(shù)據(jù)查詢
點贊
收藏

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