当前位置: 首页 > news >正文

04.领域驱动设计:了解聚合和聚合根,怎样设计聚合-学习总结

目录

1、概述

2、聚合

3、聚合根

4、怎么设计聚合

4.1 聚合的构建过程主要步骤

第 1 步:采用事件风暴。

第 2 步:选出聚合根。

第 3 步:找出与聚合根关联的所有紧密依赖的实体和值对象。

第 4 步:画出对象的引用和依赖模型。

第 5 步:多个聚合,根据业务语义和上下文一起划分到同一个限界上下文内。

4.2 聚合的一些设计原则

1.在一致性边界内,建模真正的不变条件。

2.设计小聚合。

3.通过唯一标识,引用其它聚合。

4.在边界之外,使用最终一致性。

5.通过应用层,实现跨聚合的服务调用。

5、总结

1.聚合的特点

2.聚合根的特点

3.实体的特点

4.值对象的特点

6、思考题


1、概述

在事件风暴中,我们会根据一些业务操作和行为找出实体(Entity)或值对象(ValueObject),进

而将业务关联紧密的实体和值对象进行组合,构成聚合,再根据业务语义将多个聚合划定到同一个

限界上下文(Bounded Context)中,并在限界上下文内完成领域建模

那你知道为什么要在限界上下文和实体之间增加聚合和聚合根这两个概念吗?它们的作用是什么?

怎么设计聚合?

2、聚合

在DDD中,实体和值对象是很基础的领域对象。实体一般对应业务对象,它具有业务属性和业务

行为;而值对象主要是属性集合对实体的状态和特征进行描述。

领域模型内的实体和值对象就好比个体,而能让实体和值对象协同工作的组织就是聚合,它用来确

保这些领域对象在实现共同的业务逻辑时,能保证数据的一致性

可以理解,聚合就是由业务和逻辑紧密关联的实体和值对象组合而成的,聚合是数据修改和持久化

的基本单元,每一个聚合对应一个仓储,实现数据的持久化。

聚合有一个聚合根和上下文边界,这个边界根据业务单一职责和高内聚原则,定义了聚合内部应该

包含哪些实体和值对象,而聚合之间的边界是松耦合的。按照这种方式设计出来的微服务很自然就

是“高内聚、低耦合”的。

聚合在DDD分层架构里属于领域层,领域层包含了多个聚合,共同实现核心业务逻辑。聚合内实

体以充血模型实现个体业务能力,以及业务逻辑的高内聚。跨多个实体的业务逻辑通过领域服务来

实现,跨多个聚合的业务逻辑通过应用服务来实现。

3、聚合根

聚合根的主要目的是为了避免由于复杂数据模型缺少统一的业务规则控制,而导致聚合、实体之间

数据不一致性的问题。

如果把聚合比作组织,那聚合根就是这个组织的负责人。聚合根也称为根实体,它不仅是实体,还

聚合的管理者。

首先它作为实体本身,拥有实体的属性和业务行为,实现自身的业务逻辑

其次它作为聚合的管理者,在聚合内部负责协调实体和值对象,按照固定的业务规则协同完成共同

的业务逻辑。

最后在聚合之间,它还是聚合对外的接口人,以聚合根ID关联的方式接受外部任务和请求,在上下

文内实现聚合之间的业务协同。也就是说,聚合之间通过聚合根ID关联引用,如果需要访问其它聚

合的实体,就要先访问聚合根,再导航到聚合内部实体,外部对象不能直接访问聚合内实体。

4、怎么设计聚合

DDD领域建模通常采用事件风暴,它通常采用用例分析、场景分析和用户旅程分析等方法,通过

头脑风暴列出所有可能的业务行为和事件,然后找出产生这些行为的领域对象,并梳理领域对象之

间的关系,找出聚合根,找出与聚合根业务紧密关联的实体和值对象,再将聚合根、实体和值对象

组合,构建聚合

4.1 聚合的构建过程主要步骤

以保险的投保业务场景为例。

第 1 步:采用事件风暴。

根据业务行为,梳理出在投保过程中发生这些行为的所有的实体和值对象,比如投保单、标的、客

户、被保人等等。

第 2 步:选出聚合根。

从众多实体中选出适合作为对象管理者的根实体,也就是聚合根。

判断一个实体是否是聚合根,你可以结合以下场景分析:

  • 是否有独立的生命周期

  • 是否有全局唯一ID

  • 是否可以创建或修改其它对象

  • 是否有专门的模块来管这个实体

图中的聚合根分别是投保单和客户实体。

第 3 步:找出与聚合根关联的所有紧密依赖的实体和值对象。

根据业务单一职责和高内聚原则,找出与聚合根关联的所有紧密依赖的实体和值对象。

构建出 1 个包含聚合根(唯一)、多个实体和值对象的对象集合,这个集合就是聚合

在图中我们构建了客户和投保这两个聚合。

第 4 步:画出对象的引用和依赖模型

在聚合内根据聚合根、实体和值对象的依赖关系,画出对象的引用和依赖模型。

说明一下:投保人和被保人的数据,是通过关联客户 ID 从客户聚合中获取的,在投保聚合里它们

是投保单的值对象,这些值对象的数据是客户的冗余数据,即使未来客户聚合的数据发生了变更,

也不会影响投保单的值对象数据。

从图中我们还可以看出实体之间的引用关系,比如在投保聚合里投保单聚合根引用了报价单实体,

报价单实体则引用了报价规则子实体。

第 5 步:多个聚合,根据业务语义和上下文一起划分到同一个限界上下文内
4.2 聚合的一些设计原则
1.在一致性边界内,建模真正的不变条件。

聚合用来封装真正的不变性,而不是简单地将对象组合在一起。

2.设计小聚合。

如果聚合设计得过大,聚合会因为包含过多的实体,导致实体之间的管理过于复杂,高频操作时会

出现并发冲突或者数据库锁,最终导致系统可用性变差。而小聚合设计则可以降低由于业务过大导

致聚合重构的可能性,让领域模型更能适应业务的变化。

3.通过唯一标识,引用其它聚合。

聚合之间是通过关联外部聚合根ID的方式引用,而不是直接对象引用的方式。

外部聚合的对象放在聚合边界内管理,容易导致聚合的边界不清晰,也会增加聚合之间的耦合度。

4.在边界之外,使用最终一致性。

聚合内数据强一致性,而聚合之间数据最终一致性

在一次事务中,最多只能更改一个聚合的状态。如果一次业务操作涉及多个聚合状态的更改,应采

用领域事件的方式异步修改相关的聚合,实现聚合之间的解耦。

5.通过应用层,实现跨聚合的服务调用。

为实现微服务内聚合之间的解耦,以及未来以聚合为单位的微服务组合和拆分,应避免跨聚合的领

域服务调用和跨聚合的数据库表关联。

上面的这些原则是DDD的一些通用的设计原则,还是那句话:“适合自己的才是最好的。”

在系统设计过程时,你一定要考虑项目的具体情况,如果面临使用的便利性、高性能要求、技术能

力缺失和全局事务管理等影响因素,这些原则也并不是不能突破的,总之一切以解决实际问题为出

发点

5、总结

聚合、聚合根、实体和值对象,它们之间的联系和区别:

1.聚合的特点

高内聚、低耦合,它是领域模型中最底层的边界,可以作为拆分微服务的最小单位,但不建议你对

微服务过度拆分。

一个微服务可以包含多个聚合,聚合之间的边界是微服务内天然的逻辑边界。有了这个逻辑边界,

在微服务架构演进时就可以以聚合为单位进行拆分和组合了,微服务的架构演进也就不再是一件难

事了。

2.聚合根的特点

聚合根是实体有实体的特点,具有全局唯一标识有独立的生命周期。

一个聚合只有一个聚合根,聚合根在聚合内对实体和值对象采用直接对象引用的方式进行组织和协

调,聚合根与聚合根之间通过ID关联的方式实现聚合之间的协同。

3.实体的特点

有ID标识,通过ID判断相等性ID在聚合内唯一即可。状态可变,它依附于聚合根,其生命周期由

聚合根管理。

实体一般会持久化,但与数据库持久化对象不一定是一对一的关系

实体可以引用聚合内的聚合根、实体和值对象

4.值对象的特点

无ID,不可变,无生命周期,用完即扔。

值对象之间通过属性值判断相等性。它的核心本质是,是一组概念完整的属性组成的集合,用于

描述实体的状态和特征。

值对象,尽量只引用值对象

相关文章:

04.领域驱动设计:了解聚合和聚合根,怎样设计聚合-学习总结

目录 1、概述 2、聚合 3、聚合根 4、怎么设计聚合 4.1 聚合的构建过程主要步骤 第 1 步:采用事件风暴。 第 2 步:选出聚合根。 第 3 步:找出与聚合根关联的所有紧密依赖的实体和值对象。 第 4 步:画出对象的引用和依赖模型…...

cmake-find_package链接第三方库

文章目录 基本调用形式和模块模式使用方式 之前我们是使用了绝对路径来链接OpenCV第三方库,但是现在很多库一般会自己写一些cmake文件提供给用户,用户可以直接使用其中的内置变量即可。使用的命令就是find_package。 基本调用形式和模块模式 find_packa…...

obsidian阅读pdf和文献——与zotero连用

参考: 【基于Obsidian的pdf阅读、标注,构建笔记思维导图,实现笔记标签化、碎片化,便于检索和跳转】 工作流:如何在Obsidian中阅读PDF - Eleven的文章 - 知乎 https://zhuanlan.zhihu.com/p/409627700 操作步骤 基于O…...

走方格(动态规划)

解题思路: 找边界,即行为1,列为1。 拆分问题,拆分成一次走一步,只能向右或者向下走。 解题代码: public static void main(String[] args) {int [][]arrnew int[31][31];Scanner scnew Scanner(Sys…...

基于DataKit迁移MySQL到openGauss

📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...

API网关-Apinto压缩包方式自动化安装配置教程

文章目录 前言一、Apinto安装教程1. 复制脚本2. 增加执行权限3. 执行脚本4. Apinto命令4.1 启动Apinto4.2 停止Apinto4.3 重启Apinto4.4 查看Apinto版本信息4.5 加入Apinto集群4.6 离开Apinto集群4.7 查看Apinto节点信息 5. 卸载Apinto 二、Apserver(Apinto Dashboard V3)安装教…...

内网穿透natapp使用教程(Linux)

我的使用场景:在家访问学校服务器,由于不在一个局域网,所以需要使用内网穿透,我使用的是natapp。需要在有局域网的时候做好以下步骤。 (natapp官网:https://natapp.cn/) 1. 下载客户端 &#x…...

php函数 二

一 字符串包含 1.1 str_starts_with(string $haystack, string $needle) php8版本中新函数。 检查字符串是否以指定子串开头,区分大小写。返回布尔值。 $haystack待判断的字符串,$needle需要查询的内容。 function test1() {$str "Qwe asd zx…...

IDC机房交换机核心技术与应用指南

IDC机房交换机核心技术与应用指南 ​ 在这个快速发展的数字时代,数据中心作为信息技术的心脏,不仅承载着海量数据的处理、存储和传输,更是支撑着全球企业运营和互联网服务的关键基础设施。在众多构成数据中心的组件中,IDC机房交换…...

Compose | UI组件(五) | Button 按钮组件

文章目录 前言Button 是什么?Button的创建Button显示水平方向的UI IconButton是什么?IconButton是创建 FloatingActionButton是什么?FloatingActionButton创建 ExtendedFloatingActionButton是什么? 总结 前言 随着移动端的技术不…...

【leetcode刷刷】235. 二叉搜索树的最近公共祖先 、701.二叉搜索树中的插入操作 、450.删除二叉搜索树中的节点

235. 二叉搜索树的最近公共祖先 class Solution:def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:# 递归if not root: return if root.val p.val: return pif root.val q.val: return qleft Noneright Noneif root.val > p.…...

YoloV8改进策略:BackBone改进|DCNv4最新实践|高效涨点|多种改进教程|完整论文翻译

摘要 涨点效果:在我自己的数据集上,mAP50 由0.986涨到了0.993,mAP50-95由0.737涨到0.77,涨点明显! DCNv4是可变形卷积的第四版,速度和v3相比有了大幅度的提升,但是环境搭建有一定的难度,对新手不太友好。如果在使用过程遇到编译的问题,请严格按照我写的环境配置。 …...

高中数学常识

一、大小关系 |x| > |sinx| 理由: 很明显,在圆内,弧长x>垂线sinx 3x、2x 、 1 2 \frac{1}{2} 21​x 理由: log 1 2 _\frac{1}{2} 21​​x、log 2 _2 2​x、 log 3 _3 3​x 二、(xy)? 的求法 利用二项式定理 三、平…...

docker之部署青龙面板

青龙面板是一个用于管理和监控 Linux 服务器的工具,具有定时运行脚本任务的功能。在实际情况下也可以用于一些定期自动签到等任务脚本的运行。 本次记录下简单的安装与使用,请提前安装好docker,参考之前的文章。 一、安装部署 1、拉取镜像 # …...

Type-C平板接口协议芯片介绍,实现单C口充放电功能

在现代平板电脑中,Type-C接口已经成为了一个非常常见的接口类型。相比于传统的USB接口,Type-C接口具有更小的体积、更快的传输速度和更方便的插拔体验。但是,在使用Type-C接口的平板电脑上,如何实现单C口充电、放电和USB2.0数据传…...

系统架构演变

1.1系统架构的演变 2008年以后,国内互联网行业飞速发展,我们对软件系统的需求已经不再是过去”能用就行”这种很low的档次了,像抢红包、双十一这样的活动不断逼迫我们去突破软件系统的性能上限,传统的IT企业”能用就行”的开发思…...

Oracle PL/SQL Programming 第2章:Creating and Running PL/SQL Code 读书笔记

总的目录和进度,请参见开始读 Oracle PL/SQL Programming 第6版 暂不考虑系统设计或单元测试之类的任务,所有 PL/SQL 程序员必须熟悉的基本操作任务包括: 浏览数据库创建和编辑 PL/SQL 源代码编译 PL/SQL 源代码,并更正编译器注…...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Swiper容器组件

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Swiper容器组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Swiper容器组件 滑块视图容器,提供子组件滑动轮播显示的能力。…...

『建议收藏』OpenAI官方出的Prompt提示词教程中文版来了!

一些结论 六大策略: 写清晰的指令 提供参考文本 将复杂任务分解为更简单的子任务 给模型时间“思考” 使用外部工具 系统性测试变化 提高结果质量的六大策略 写清晰的指令 这些模型无法读懂你的想法。如果输出过长,要求简短回复;如果输出过于简单…...

牛刀小试 - C++ 推箱子小游戏

参考文档 C笔记:推箱子小游戏 copy函数 memcpy()函数用法(可复制数组) 使用memcpy踩出来的坑,值得注意 完整代码 /********************************************************************* 程序名:推箱子小游戏 说明&#x…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

测试markdown--肇兴

day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...