成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聚合和聚合根:怎樣設計聚合?你知道嗎?

開發 前端
聚合間的引用依靠關聯外部聚合根 ID 來實現,而非直接的對象引用。若把外部聚合的對象納入本聚合邊界內管理,不僅會模糊聚合邊界,還會提升聚合間的耦合程度,所以要通過唯一標識引用其它聚合。

聚合

在 DDD 中,實體和值對象是很基礎的領域對象。實體一般對應業務對象,它具有業務屬性和業務行為;而值對象主要是屬性集合,對實體的狀態和特征進行描述。但實體和值對象都只是個體化的對象,它們的行為表現出來的是個體的能力。

那聚合在其中起什么作用呢?

社會由個體組成,我們每個人都是其中一員。隨著社會發展,社團、機構、部門等組織應運而生,我們從個體逐漸成為組織的一部分。在組織中,大家協同工作,朝著共同目標奮進,能發揮出更大的力量。

在領域模型里,實體和值對象類似于個體,而聚合則如同讓實體和值對象協同工作的組織。聚合確保這些領域對象在實現共同業務邏輯時,數據保持一致。簡單來說,聚合由業務和邏輯緊密關聯的實體和值對象組合而成,是數據修改和持久化的基本單元。每個聚合對應一個倉儲,用于實現數據持久化。

聚合有聚合根和上下文邊界。這個邊界依據業務單一職責和高內聚原則,界定了聚合內部包含的實體和值對象。而且,聚合之間的邊界是松耦合的。按此方式設計的微服務,自然具備“高內聚、低耦合”的特性。

在DDD分層架構中,聚合屬于領域層。領域層包含多個聚合,共同實現核心業務邏輯。聚合內的實體采用充血模型,實現個體業務能力以及業務邏輯的高內聚。

跨多個實體的業務邏輯通過領域服務實現,跨多個聚合的業務邏輯則通過應用服務實現。例如,若某個業務場景需要同一個聚合中的A和B兩個實體共同完成,那么這段業務邏輯可用領域服務實現;若業務邏輯需要聚合C和聚合D中的兩個服務共同完成,這時就可以用應用服務來組合這兩個服務。

聚合根

聚合根的主要作用,是防止復雜數據模型因為缺乏統一業務規則的管控,而出現聚合、實體之間數據不一致的情況。在傳統數據模型里,每個實體地位平等,若任由實體隨意調用和修改數據,極有可能造成實體間數據邏輯的混亂。要是采用鎖的方式來解決,又會增加軟件復雜度,降低系統性能。

如果把聚合看作一個組織,那么聚合根就相當于這個組織的負責人,也被稱為根實體。它既是實體,又承擔著聚合管理者的角色。

從實體角度來看,聚合根具備實體的屬性和業務行為,能夠實現自身的業務邏輯。

作為聚合的管理者,聚合根在聚合內部發揮著協調作用,確保實體和值對象依照既定的業務規則,協同完成共同的業務邏輯。

在聚合之間,聚合根是聚合對外的接口。它通過聚合根 ID 關聯的方式,接收外部任務和請求,并在上下文范圍內實現聚合之間的業務協作。也就是說,聚合之間是通過聚合根 ID 進行關聯引用的。外部對象若要訪問其他聚合的實體,不能直接進行訪問,而是要先訪問聚合根,再通過聚合根導航到聚合內部的實體。

怎樣設計聚合?

DDD 領域建模通常采用事件風暴,它通常采用用例分析、場景分析和用戶旅程分析等方法,通過頭腦風暴列出所有可能的業務行為和事件,然后找出產生這些行為的領域對象,并梳理領域對象之間的關系,找出聚合根,找出與聚合根業務緊密關聯的實體和值對象,再將聚合根、實體和值對象組合,構建聚合。

下面我們以保險的投保業務場景為例,看一下聚合的構建過程主要都包括哪些步驟。

圖片圖片

在投保過程中構建聚合,可按以下步驟進行:

第一步:采用事件風暴梳理實體和值對象

基于業務行為,運用事件風暴方法,全面梳理在投保過程中涉及這些行為的所有實體和值對象。例如,常見的有投保單、標的、客戶、被保人等。

第二步:確定聚合根

從眾多實體中挑選出適合擔任對象管理者的根實體,即聚合根。判斷一個實體能否成為聚合根,可結合以下場景展開分析:該實體是否擁有獨立的生命周期;是否具備全局唯一 ID;是否能夠創建或修改其他對象;是否存在專門的模塊對其進行管理。在相關圖示中,投保單和客戶實體就是聚合根。

第三步:構建聚合

依據業務單一職責和高內聚原則,找出與聚合根緊密關聯、相互依賴的所有實體和值對象。由此構建出一個對象集合,這個集合包含唯一的聚合根以及多個實體和值對象,這便是聚合。在圖中,我們構建出了客戶和投保這兩個聚合。

第四步:繪制對象引用和依賴模型

在聚合內部,根據聚合根、實體和值對象之間的依賴關系,繪制出對象的引用和依賴模型。需要特別說明的是,投保人和被保人的數據,是通過關聯客戶 ID 從客戶聚合中獲取的,在投保聚合里,它們屬于投保單的值對象。這些值對象的數據是客戶數據的冗余,即便未來客戶聚合的數據有所變動,也不會對投保單的值對象數據產生影響。從圖中還能清晰看到實體之間的引用關系,比如在投保聚合中,投保單聚合根引用了報價單實體,而報價單實體又引用了報價規則子實體。

第五步:劃分限界上下文

將多個聚合依據業務語義和上下文,劃分到同一個限界上下文內。

聚合的一些設計原則

我們不妨先看一下《實現領域驅動設計》一書中對聚合設計原則的描述,原文是有點不太好理解的,我來給你解釋一下。

在一致性邊界內建模真正的不變條件是 DDD 設計中的重要原則。聚合的意義在于封裝真正的不變性,并非簡單拼湊對象。每個聚合內部都有一套既定的業務規則,其中的實體和值對象遵循這些規則運轉,以此保證對象數據的一致性。而在聚合邊界之外的事物,與該聚合毫無關聯,這也正是聚合能夠達成業務高內聚的關鍵因素。

設計小聚合也十分關鍵。聚合規模若設計得過大,會因涵蓋過多實體,使實體間管理難度大增。在高頻操作場景下,易引發并發沖突或數據庫鎖問題,最終降低系統可用性。與之相對,小聚合設計能減少因業務擴張導致聚合重構的幾率,讓領域模型對業務變化的適應性更強。

聚合間的引用依靠關聯外部聚合根 ID 來實現,而非直接的對象引用。若把外部聚合的對象納入本聚合邊界內管理,不僅會模糊聚合邊界,還會提升聚合間的耦合程度,所以要通過唯一標識引用其它聚合。

聚合內部數據需保持強一致性,而聚合之間實現最終一致性即可。一次事務中,最多只能改變一個聚合的狀態。要是業務操作涉及多個聚合狀態變更,應借助領域事件異步修改相關聚合,從而實現聚合間的解耦(領域事件相關內容會在后續詳細講解),這就是在邊界之外使用最終一致性的原則。

為實現微服務內聚合間的解耦,以及滿足未來以聚合為單位的微服務組合與拆分需求,應規避跨聚合的領域服務調用和數據庫表關聯,也就是要通過應用層實現跨聚合的服務調用 。

不過,要牢記 “適合自己的才是最好的”。在系統設計時,必須充分考量項目的實際情況。面對使用便利性、高性能需求、技術能力短板以及全局事務管理等因素時,這些原則并非不可變通,一切都應以解決實際問題為根本出發點。

責任編輯:武曉燕 來源: 二進制跳動
相關推薦

2022-12-12 09:13:45

global聚合filters

2024-02-28 09:07:58

鏈路聚合模式

2025-06-27 09:32:47

GoRedis單線程

2010-10-11 16:19:30

Mysql聚合函數

2022-03-04 08:00:00

Java Strea數據函數

2018-05-21 08:07:35

聚合MongoDBSchema

2023-10-06 23:14:07

VLAN網絡性能

2024-01-01 08:25:53

ViewSurface框架

2022-12-28 08:16:16

metric聚合java

2010-10-25 17:08:34

oracle聚合函數

2023-12-20 08:23:53

NIO組件非阻塞

2023-12-12 08:41:01

2023-04-26 10:21:04

2024-04-30 09:02:48

2011-12-26 15:19:20

聚合

2024-11-26 14:29:48

2012-08-06 15:59:17

MongoDB

2023-09-01 07:38:45

ArrayListArrayst實線類

2019-02-12 11:15:15

Spring設計模式Java

2018-05-11 15:53:59

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧洲一级黄 | 欧美6一10sex性hd | 国产a区 | 久久国产精品视频 | 中日韩欧美一级片 | 成人一区二区在线 | 8x国产精品视频一区二区 | 蜜臀网 | 国产精品久久久久久久午夜 | 日韩在线资源 | 极情综合网 | 97精品超碰一区二区三区 | 日韩av在线一区二区 | 国产一区二区在线91 | 久久九九免费 | 国内久久精品 | 欧美精品成人一区二区三区四区 | 国产99久久久久 | 北条麻妃一区二区三区在线观看 | 亚洲精品18 | 亚洲精品乱码久久久久久蜜桃91 | 国产高清不卡 | 日韩在线观看视频一区 | 美国一级毛片a | 麻豆av网站| 欧美精品99 | 亚洲欧美日韩久久久 | 国产中文视频 | 精品国产乱码久久久久久影片 | 国产精品久久久久久久久久三级 | 日韩免费在线观看视频 | 国产一在线观看 | 麻豆天堂| 欧美电影免费观看 | 中文av在线播放 | 亚洲在线免费 | 成人福利视频网站 | 欧美日本韩国一区二区三区 | 国产一区视频在线 | 韩日一区 | 精品久久99 |