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} 21x 理由: log 1 2 _\frac{1}{2} 21x、log 2 _2 2x、 log 3 _3 3x 二、(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…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
