25.DDD数量关系
学习视频来源:DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid=1940048&ctype=0
文章目录
- 关系型数据库的数量关系
- 领域模型的数量关系
- 实现聚合数量关系
- 聚合内
- 聚合间
- 具体说明
- 代码
- 数量关系是本质吗?
- 领域对象之间的数量关系是不变的吗?
- 为什么领域对象之间存在这样的数量关系?
关系型数据库的数量关系
在设计关系型数据库的时候,我们会设计很多的表,每个表都是一个实体。表和表之间或者说实体和实体之间数量可能会存在某种约束,比如一对一、一对多、多对多。
领域模型的数量关系
在面对象的设计的时候,对象和对象之间也会存在这种数量关系。因为在领域驱动设计中,是采用面向对象的方法设计领域模型,所以领域模型中也会具有这种数量关系,而且这个数量关系很重要。不过我们会更关心它是如何产生的这种数量关系,而不只是关心它们之间的数量关系是什么。
实现聚合数量关系
在实现的时候,聚合内和聚合间的数量关系是存在很大差别的。
聚合内
- 导航采用对象引用实现。因为在同一个聚合内,所以需要同时载入内存,同时持久化。
- 尽量隐藏聚合内部对象的数量关系
通过定义函数,维护数量关系,不要直接把暴露出去让外部操作
聚合间
- 导航采用持有id实现。避免载入A聚合时导致载入了B聚合。
具体说明
up主视频里说的有点抽象了,我这里画了张图具体说明一下。如下图,聚合内会有多个对象,也就是图中的聚合根、实体、值对象。订单作为聚合根,直接持有和它在同一个聚合内的对象引用。而订单和商品作为不同的聚合,订单持有的是商品聚合根的唯一标识,比如商品id。
代码
@Data
public class Order {private Long orderId; // 订单id// 聚合内private List<OrderItem> orderItemList;private Money money;private Address address;// 聚合间private List<Long> productIdList; // 商品id列表// 通过构造函数,使得必要的对象可能同时载入内存public Order(Long orderId, Money money) {this.orderId = orderId;this.money = money;}// 通过定义函数,维护数量关系,不要直接把暴露出去让外部操作public void addOrderItem(List<OrderItem> orderItems) {if (orderItems.size() > 10) {throw new RuntimeException();}// ...// ....}
}@Data
public class Product {// 聚合内private List<ProductDetail> productDetailList;private Color color;private Comment comment;private Size size;
}
数量关系是本质吗?
领域对象之间的数量关系是不变的吗?
答案显然是否,它们之间的关系会随着业务场景发生变化。比如一个订单刚开始对应一次支付,但随着业务的发展,可能会变成一个订单可以支持多次支付,也有可能变成多个订单可以合并,被一次支付掉。
为什么领域对象之间存在这样的数量关系?
数量关系不是本质,功能才是。领域之间之所以是存在这样的数量关系,是因为这样的数量关系为了实现某个功能而特意设计的。当功能变更的时候,数量关系就可能发生变化。
所以我们在设计领域模型的时候,不会一上来就去谈两个领域对象之间的数量关系,我们更关心在哪个动作、哪个命令执行的时候,它需要在这个时刻从一个领域对象,找到另外一个领域象。怎么找?找了多少个?是关心这个具体场景下的这些问题。所以我们是以业务功能作为切入点的。如果在这个功能需要,我们就把这个关系数量加上;如果这个功能不需要,我们就不加,因为加了没有意义。不仅是数量关系,聚合内持有的哪些数据也是由功能决定的。领域对象之间数量关系是一个结果,它可以帮助别人理解领域模型,但它不是领域对象之间存在这样的数量关系的原因。
这里我加个具体的例子,比如一个订单可能对应多次支付记录,如果没有功能需要使订单和支付关联起来,我们不需要维护二者的关系,不需要在订单中持有支付记录的引用或者id列表。但是如果新加了一个功能,比如需要支持查看某个订单下关联的支付记录,这样二者就发生了联系,那么这时候我们就需要加上这个数量关系,让订单持有支付记录的引用或者id列表。
可以看到,领域对象是否存在这样的数量关系取决于功能是否需要。
相关文章:

25.DDD数量关系
学习视频来源:DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid1940048&ctype0 文章目录 关系型数据库的数量关系领域模型的数量关系实现聚合数量关系聚合内聚合间具体说明代码 数量关系是本质吗?领域对象之…...

Linux应用开发————线程池
线程池 定义:简单来说,就是存放多个线程的池子。当创建线程池时,就给池中存放一些线程,如果有任务要执行,就从池中取出一个线程执行任务,依次类推;当所有线程都在执行任务时,其他任务…...

Spring Boot 集成阿里云OSS 完成文件上传下载
前言: 文件上传下载在项目开发中是一个非常常见的业务场景,在云服务上还没有兴起的时候,一般来说都会把文件单独存放到文件服务器上,随着云服务的兴起,各类云服务厂商都提供了 OSS 服务,本篇我们分享 Spri…...

使用ERA5数据绘制风向玫瑰图的简易流程
使用ERA5数据绘制风向玫瑰图的简易流程 今天需要做一个2017年-2023年的平均风向的统计,做一个风向玫瑰图,想到的还是高分辨率的ERA5land的数据(0.1分辨率,逐小时分辨率,1950年至今)。 风向,我分为了16个&…...

测试脚本并发多进程:pytest-xdist用法
参考:https://www.cnblogs.com/poloyy/p/12694861.html pytest-xdist详解: https://www.cnblogs.com/poloyy/p/14708825.html 总 https://www.cnblogs.com/poloyy/category/1690628.html...

数据可视化的Python实现
一、GDELT介绍 GDELT ( www.gdeltproject.org ) 每时每刻监控着每个国家的几乎每个角落的 100 多种语言的新闻媒体 -- 印刷的、广播的和web 形式的,识别人员、位置、组织、数量、主题、数据源、情绪、报价、图片和每秒都在推动全球社会的事件,GDELT 为全…...

【Linux系列】Linux 系统配置文件详解:`/etc/profile`、`~/.bashrc` 和 `~/.bash_profile`
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

uni-app实现小程序、H5图片轮播预览、双指缩放、双击放大、单击还原、滑动切换功能
前言 这次的标题有点长,主要是想要表述的功能点有点多; 简单做一下需求描述 产品要求在商品详情页的头部轮播图部分,可以单击预览大图,同时在预览界面可以双指放大缩小图片并且可以移动查看图片,双击放大࿰…...

游戏引擎学习第45天
仓库: https://gitee.com/mrxiao_com/2d_game 回顾 我们刚刚开始研究运动方程,展示了如何处理当人物遇到障碍物时的情况。有一种版本是角色会从障碍物上反弹,而另一版本是角色会完全停下来。这种方式感觉不太自然,因为在游戏中,…...

electron常用方法
一,,electron设置去除顶部导航栏和menu 1,electron项目 在创建BrowserWindow实例的main.js页面添加frame:false属性 2,electron-vue项目 在src/main/index.js文件下找到创建窗口的方法(createWindow)&…...

【Spark】Spark Join类型及Join实现方式
如果觉得这篇文章对您有帮助,别忘了点赞、分享或关注哦!您的一点小小支持,不仅能帮助更多人找到有价值的内容,还能鼓励我持续分享更多精彩的技术文章。感谢您的支持,让我们一起在技术的世界中不断进步! Sp…...

meta llama 大模型一个基础语言模型的集合
LLaMA 是一个基础语言模型的集合,参数范围从 7B 到 65B。我们在数万亿个 Token 上训练我们的模型,并表明可以专门使用公开可用的数据集来训练最先进的模型,而无需诉诸专有的和无法访问的数据集。特别是,LLaMA-13B 在大多数基准测试…...

JAVA爬虫获取1688关键词接口
以下是使用Java爬虫获取1688关键词接口的详细步骤和示例代码: 一、获取API接口访问权限 要使用1688关键词接口,首先需要获取API的使用权限,并了解接口规范。以下是获取API接口的详细步骤: 注册账号:在1688平台注册一…...

操作系统——内存管理
1、什么是虚拟内存?它是如何实现的?虚拟内存与物理内存之间有什么关系? 虚拟内存是操作系统提供的一种内存管理机制,它使程序认为自己拥有连续的内存空间,但实际上内存可能被分散存储在物理内存和磁盘交换空间中。 虚…...

android studio 模拟器不能联网?
模拟器路径: C:\Users\Administrator\AppData\Local\Android\Sdk\emulator\emulator.exe.关闭所有AVD设备实例 导航至: C:\Users\userName\AppData\Local\Android\Sdk\emulator查看模拟器名称 AdministratorDESKTOP-6JB1OGC MINGW64 ~/AppData/Local/…...

CTF-WEB: 目录穿越与模板注入 [第一届国城杯 Ez_Gallery ] 赛后学习笔记
step1 验证码处存在逻辑漏洞,只要不申请刷新验证码就一直有效 字典爆破得到 admin:123456 step2 /info?file../../../proc/self/cmdline获得 python/app/app.py经尝试,读取存在的目录时会返回 A server error occurred. Please contact the administrator./info?file.…...

数据结构6.4——归并排序
基本思想: 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个…...

【html 常用MIME类型列表】
本表仅列出了常用的MIME类型,完整列表参考文档。 浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理 URL,因此 Web 服务器在响应头中添加正确的 MIME 类型非常重要。 如果配置不正确,浏览器可能会曲解文件内容…...

Linux之vim编辑器
vi编辑器是所有Unix及linux系统下标准的编辑器,类似于Windows系统下的记事本。很多软件默认使用vi作为他们编辑的接口。vim是进阶版的vi,vim可以视为一种程序编辑器。 前言: 1.文件准备 复制 /etc/passwd文件到自己的目录下(不…...

【工具介绍】可以批量查看LableMe标注的图像文件信息~
在图像处理和计算机视觉领域,LabelMe是一个广泛使用的图像标注工具,它帮助我们对图像中的物体进行精确的标注。但是,当标注完成后,我们常常需要一个工具来批量查看这些标注信息。 今天,我要介绍的这款exe程序…...

2024年山西省第十八届职业院校技能大赛 (高职组)“信息安全管理与评估”赛项规程
2024年山西省第十八届职业院校技能大赛 (高职组)“信息安全管理与评估”赛项规程 一、赛项名称 赛项名称:信息安全管理与评估 英文名称:Information Security Management and Evaluation 赛项组别:高职教师组 赛项归属…...

STM32完全学习——STemWin的移植小插曲
一、移植编译的一些问题 新版的STemWin的库没有区别编译器,只有一些这样的文件,默认你将这些文件导入到KEIL中,然后编译就会有下面的错误。 ..\MEWIN\STemWin\Lib\STemWin_CM4_wc16.a(1): error: A1167E: Invalid line start ..\MEWIN\STe…...

Java——IO流(下)
一 (字符流扩展) 1 字符输出流 (更方便的输出字符——>取代了缓冲字符输出流——>因为他自己的节点流) (PrintWriter——>节点流——>具有自动行刷新缓冲字符输出流——>可以按行写出字符串,并且可通过println();方法实现自动换行) 在Java的IO流中…...

avue-crud 同时使用 column 与 group 的问题
场景一:在使用option 中的column 和 group 进行表单数据新增操作时,进行里面的控件操作时,点击后卡死问题,文本没问题 其它比如下拉,单选框操作,当删除 column 中的字段后, group 中的可以操作 …...

深入解析 Pytest 中的 conftest.py:测试配置与复用的利器
在 Pytest 测试框架中,conftest.py 是一个特殊的文件,用于定义测试会话的共享配置和通用功能。它是 Pytest 的核心功能之一,可以用于以下目的: 【主要功能】 1、定义共享的 Fixture (1)conftest.py 文件可…...

JAVA |日常开发中Websocket详解
JAVA |日常开发中Websocket详解 前言一、Websocket 概述1.1 定义1.2 优势 二、Websocket 协议基础2.1 握手过程2.2 消息格式2.3 数据传输方式 三、Java 中使用 Websocket3.1 Java WebSocket API(JSR - 356)3.2 第三方库(如 Tyrus&…...

Typora教程
目录 一、下载安装 二、激活 1.激活 2.解决激活提示窗口 一、下载安装 去官网下载Typora安装,我的是1.9.5版本 二、激活 1.激活 根据路径找到Typora/resources/page-dist/static/js 使用记事本打开LicenseIndex文件,如下图: 按住快捷…...

泛微E9常见API保姆级详解!!!!
前言 在泛微前端开发过程中,虽然大部分是对流程以及流程逻辑的调整,但是还是会有一些小的个性化需求是需要借助JS来实现的。 比如:对同一组数据,前后变化不一样时,需要对这组变化后的数据进行标红处理;对提…...

UniApp配置使用原子化tailwindcss
参考视频 创建项目 新建项目选择uniapp - vue版本这里我选择3 - 点击创建即可 创建完成后,如果是要编译到小程序的项目则可以先将项目运行到小程序打开了 初始化package.json 执行 npm init -y安装和配置 安装 npm i -D tailwindcss postcss autoprefixer # 安…...

02. Docker:安装和操作
目录 一、Docker的安装方式 1、实验环境准备 1.1 关闭防火墙 1.2 可以访问网络 1.3 配置yum源 2、yum安装docker 2.1 安装docker服务 2.2 配置镜像加速 2.3 启动docker服务 3、二进制安装docker 3.1 下载或上传安装包并解压 3.2 配置使用systemctl管理 3.3 配置镜像…...

做电影网站需要什么服务器/百度推广怎么收费
1、操作系统 操作系统有很多, Centos、Suse、Ubuntu、Debian等等。真正在开发中用到最多的就是Centos,而且老版本的还比较多。为了以后的工作考虑,选择Centos7 作为自己的第一开发环境搭建的操作系统。 2、桌面环境 个人对桌面环境也有过一些了解。大概常…...

国企网站建设合同/深圳网站设计公司
文章目录一.原型链机制1. 原型链的本质2. 引用类型的构造函数3. 基本类型的包装类二. 对象与属性1. 对象直接打点验证某个属性是否存在4. instanceof 运算符三. 继承1. 原型链继承2. 构造函数继承3. 组合继承一.原型链机制 1. 原型链的本质 只要是对象,一定有原型…...

上海企业做网站/做网站怎么做
LESS 允许开发者自定义变量,变量可以在全局样式中使用,变量使得样式修改起来更加简单。例如: border-color : #b5bcc7;.mythemes tableBorder{border : 1px solid border-color;} 经过编译生成的 CSS 文件如下: .mythemes tableBo…...

网站建设的相关新闻/郑州网站制作公司哪家好
Tomcat 服务器网页部署,登录需用户名/密码,编写了一个简单的Python脚本来测试一些简单的弱口令。 测试环境:Tomcat版本 7.0 登录界面采用basic认证,Base 64加密一下,模拟浏览器进行发包 据测试,每个用户名输…...

1000学习做网站贵吗/观看b站的广告网站平台
2019独角兽企业重金招聘Python工程师标准>>> binSort.cpp /** 这里是主函数的执行文件 * binSort.cpp */ #include<iostream> #include"studentrecord1.h" #include"chainwithiterator.h" #include"myexceptions.h"void…...

中文域名查询网站/百度网页浏览器
第 1 步:集成环信SDK 方式一: 推荐使用Cocoapods集成环信SDK。Cocoapods提供了一个简单的依赖管理系统,避免手动导入产生的错误(首先需要确认已经安装了Cocoapods)。 详情请见http://blog.csdn.net/fantasy_jun/art…...