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,不可变,无生命周期,用完即扔。

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

描述实体的状态和特征。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/353909.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3框架基本使用

一、安装包管理工具 vite和vue-cli一样,都是脚手架。 1.node版本 PS E:\vuecode\vite1> node -v v18.12.12.安装yarn工具 2.1 yarn简单介绍 yarn是一个包管理工具,也是一个构建、打包工具 yarn需要借助npm进行安装:执行的命令行npm i…

找不同-《企业应用架构模式》2024典藏版

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 以下是2004年《企业应用架构模式》中译本和2024年《企业应用架构模式》典藏版译本的页面。 您能从中找出至少10处不同吗? 如何选择UMLChina服务 UMLChina公众号精选&…

Blender教程(基础)-面的细分与删除、挤出选区-07

一、Blender之面的细分 新建一个立方体,在编辑模式下、选中一个面。 在选中的面上单击右键弹出细分选项,选择细分。 在选中细分后、会默认细分1次。修改细分次数在左下角 二、Blender之面的删除 选择中需要操作的面,在英文状态下按X键弹…

VSCode 1.85.0更新的3个实用功能

1、单个文件可直接拖拽为独立窗口 当单文件过长,直接分成两个视图就不用上下频繁滚动 2、将终端移动到编辑器区域 此时,终端也可像文件一样拖拽为独立窗口 3、文件夹目录粘性头部 默认关闭,需要设置 "workbench.tree.enableStickyScro…

Linux权限的概念,shell命令以及运行原理

目录 1.shell命令以及运行原理2.Linux权限2.1Linux中的两类用户2.2Linux权限管理2.2.1文件访问者的分类(人)2.2.2文件类型和访问权限(事物属性)2.2.3文件的类型以及权限的缩写2.2.4文件权限值的表示方法2.2.5文件访问权限的相关设…

HTML 曲线图表特效

下面是代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>基于 ApexCharts 的 HTML5 曲线图表DEMO演示</title><style> body {background: #000524; }#wrapper {padding-top: 20px;background: #000524;b…

opencv#33 边缘检测

边缘检测原理 图像的每一行每一列都可以看成是一个连续的信号经过离散后得到的数值&#xff0c;例如上图左侧给出的图像由黑色到白色的一个信号&#xff0c;也就是图像中某一行像素变化是由黑色逐渐到白色&#xff0c;我们将其对应在一个坐标轴中&#xff0c;将像素值的大小对应…

sysfs: cannot create duplicate filename ‘/devices/virtual/leds/led1‘问题查找及解决

问题描述&#xff1a;安装模块时出现如下错误&#xff1a; [rootVinxin_PC leds]# cd /driver_Test/ [rootVinxin_PC driver_Test]# ls app leds-s5pv210.ko [rootVinxin_PC driver_Test]# lsmod Module Size Used by Not tainted [rootVin…

最全全国十七个数据入表和资产化案例深度解析

2024年1月1日起&#xff0c;财政部会计司发布的《企业数据资源相关会计处理暂行规定》正式施行&#xff0c;规定为数据资源的会计处理提供了明确的指导原则。这一里程碑事件也标志着我国在数据资产入表领域正式进入实际操作阶段&#xff0c;随后&#xff0c;数据资产入表在全国…

stable diffusion学习笔记——文生图(一)

模型设置 基本模型 基本模型也就是常说的checkpoint&#xff08;大模型&#xff09;&#xff0c;基本模型决定了生成图片的主体风格。 如上图所示&#xff0c;基本模型的后缀为.safetensors。需要存放在特定的文件夹下。 如果用的是启动器&#xff0c;可以在启动器内直接下载。…

2024年黑龙江省安全员C证证考试题库及黑龙江省安全员C证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年黑龙江省安全员C证证考试题库及黑龙江省安全员C证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考…

(java)idel中将对与json的相互转

1、目录结构 2、导入包 在模块下面建立lib目录将包导入模块中 包的百度网盘 链接&#xff1a;https://pan.baidu.com/s/1abNF8cOTeNb00rM7tp04iQ?pwd39wc 提取码&#xff1a;39wc 3、建立两个测试类person和dog类 public class Dog {private String name;private int age…

STM32标准库——(5)EXTI外部中断

1.中断系统 中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行 中断优先级&#xff…

CMake 完整入门教程(一)

1 前言 每一次学习新东西都是很有乐趣的&#xff0c;虽然刚开始会花费时间用来学习&#xff0c;但是实践证明&#xff0c;虽然学习新东西可能会花费一些时间&#xff0c;但是它们带来的好处会远远超过这些花费的时间。学习新东西是值得的&#xff0c;也是很有乐趣的。 网络上…

六、Kotlin 类型进阶

1. 类的构造器 & init 代码块 1.1 主构造器 & 副构造器在使用时的注意事项 & 注解 JvmOverloads 推荐在类定义时为类提供一个主构造器&#xff1b; 在为类提供了主构造器的情况下&#xff0c;当再定义其他的副构造器时&#xff0c;要求副构造器必须调用到主构造器…

安全防御{第三次作业(在第二次作业上添加点需求)}

目录 需求&#xff1a; 拓扑图&#xff1a; 注意&#xff1a;先打开防火墙web界面&#xff0c;在此不做演示 1.要求一&#xff1a;&#xff0c;生产区在工作时间内可以访问服务器区&#xff0c;仅可以访问http服务器 2.要求二&#xff1a;办公区全天可以访问服务器区&#…

RISC-V RVWMO 内存模型解释

RISC-V RVWMO 内存模型解释 引言 本文介绍 RISC-V RVWMO 内存模型。RVWMO 内存模型定义了什么样的全局内存顺序才是合法的。本引言部分将解释为什么会出现不合法的全局内存顺序&#xff0c;以及为什么需要内存模型。 首先引起乱序的全局内存顺序&#xff08;指令重排序&…

静态分析C语言生成函数调用关系的利器——cally和egypt

大纲 准备工作安装graphviz安装cally安装egypt简单分析GCC产生RTL&#xff08;Register transfer language&#xff09;文件callyegypt总结 高级分析callyegypt 总结参考资料 在《静态分析C语言生成函数调用关系的利器——cflow》和《静态分析C语言生成函数调用关系的利器——c…

What is `@Scheduled` does?

Scheduled 是Spring框架中用于定时任务调度的注解&#xff0c;它允许我们在类的方法上声明一个方法作为定时任务&#xff0c;由Spring容器统一管理和执行。使用此注解后&#xff0c;Spring会根据注解中的属性配置&#xff0c;按照指定的时间规则自动调用该方法。 public class…

网络编程小总结

【一】网络编程 互联网的本质就是一些网络协议 【1】网络开发架构 &#xff08; 1 &#xff09; C / S 架构 C : client &#xff08;客户端&#xff09; S: server (服务端) APP - 就是服务端 C/S 架构通过客户端软件和服务器之间的交互&#xff0c;实现了前端界面和后…