《软件方法(下)》8.3.4.6 DDD话语“聚合”中的伪创新(1)

DDD领域驱动设计批评文集

做强化自测题获得“软件方法建模师”称号

《软件方法》各章合集


8.3 建模步骤C-2 识别类的关系

8.3.4 识别关联关系

8.3.4.6 DDD话语“聚合”中的伪创新

DDD话语中也有“聚合”。Eric Evans的“Domain-Driven Design: Tackling Complexity in the Heart of Software”书中是这样说的:

An AGGREGATE is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each AGGREGATE has a root and a boundary. ……The root is the only member of the AGGREGATE that outside objects are allowed to hold references to, ……

一个AGGREGATE是一簇相关联的对象,我们把它作为数据变化的单元来对待。每个AGGREGATE有一个根和一个边界。……根是AGGREGATE的成员中唯一允许外部对象持有引用的,……

以上文字提到了两个概念:

(1)aggregate(聚合体),指整个聚合/组合结构。

(2)aggregate root(聚合根),聚合/组合结构中扮演整体的对象。

先阐明本书对于这两个概念的观点:

两者都不提倡使用。其中,aggregate属于冗余概念,aggregate root属于错误概念。

接下来说一下原因。

我们以图8-138中Grady Booch关于系统结构的一段隐喻作为素材,比较aggregate、aggregate root以及前文所说的UML的aggregation(composition)。

图片

图8-138 摘自《面向对象分析与设计(原书第2版)》,Grady Booch 著;冯博琴 等 译,英文原版出版于1994年

把图8-138的内容用类图和组合结构图表达如图8-139,并在标出三个用语的位置。

图片

图8-139 三个用语的位置

(1)aggregation是本质概念

aggregation指类之间的“整体-部分”关联,可以称为“聚合关联”。

例如,图8-139中,“植物”和“根”、“茎”、“叶”存在aggregation关联,说明可能会存在“植物”对象,它的组成部件是“根”、“茎”、“叶”对象。

根据前文提到的本书观点,“整体-部分”关联就是“组合(composition)”,因此,图8-139以及后面的图形都会使用实心菱形。

(2)aggregate是冗余概念

在面向对象建模领域,aggregate并非Eric Evans在“Domain-Driven Design”书中首先使用。

1991年,James Rumbaugh等人的书“Object-Oriented Modeling and Design”中就阐述了aggregation和aggregate,如图8-140所示。

图片

图8-140 摘自Object-Oriented Modeling and Design,James Rumbaugh et al. ,1991

可以看到,图8-140中的标题是Aggregation,不是Aggregate。

1999年出版的“The Unified Modeling Language Reference Manual(UML参考手册)”第1版中,也有“aggregate”词条,但内容只有一句话,接下来的“aggregation”词条的内容却达4页之多,如图8-141。

图片

图8-141 摘自The Unified Modeling Language Reference Manual,James Rumbaugh et al. ,1999

可以看出来,UML规范认为aggregation才是本质的概念。

为什么两者待遇不一样?

因为aggregate只是类(类图上的结点)在aggregation关联(类图上的边)中扮演的一个角色。同一个类可能在某个aggregation关联中扮演aggregate(聚合体,整体),在另外一个aggregation关联中扮演part(部件)。

我们进一步扩展图8-139中的类图,得到图8-142。可以看到,包括“植物”在内的很多类,既扮演整体,也扮演部分。

图片

图8-142 既扮演整体又扮演部分

一个对象可能由很多部件(最小部件是其简单属性值)组成,同时它又可以成为更大对象的部件。

离开特定的关联,指着一个对象说“它是整体”、“它是aggregate”或“它是aggregate root”,都是不合适的,除非只存在一级整体-部分结构。

这也是现在DDD实践中aggregate的现状——再多一级的话,不妨祭出“性能”遮羞布遮掩过去——“这得加载多少数据啊,会影响性能的!”。

即使只存在一级整体-部分结构,也没有必要在类上标注“aggregate root”,或者圈一个边界说这是一个aggregate,关系上的菱形标记已经提供了足够的信息。

图片

图8-143 这两个标记都是冗余的

同理,如果要体现某些领域驱动设计实践投资少、见效快、产量高、门槛低、仪式感十足的特点,就可以考虑图8-143的标记。

(3)aggregate root是伪创新

在“Domain-Driven Design”之前的软件开发书籍中,没有出现aggregate root的说法,aggregate root应该是Eric Evans的造词。

可惜,这是一个伪创新。

我们再看一遍“Domain-Driven Design”中的描述:

An AGGREGATE is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each AGGREGATE has a root and a boundary. ……The root is the only member of the AGGREGATE that outside objects are allowed to hold references to, ……

一个AGGREGATE是一簇相关联的对象,我们把它作为数据变化的单元来对待。每个AGGREGATE有一个根和一个边界。……根是AGGREGATE的成员中唯一允许外部对象持有引用的,……

以图8-139为例,按照这个说法,我们可以说:

①(“植物”+“根”+“茎”+“叶”)等一簇相关联的对象形成了一个aggregate。

②其中“植物”是该aggregate的aggregate root。

先来看①的问题。

图片

图8-144 对象不需要也不能和其部件并列

如图8-144,“植物”已经包括“根”、“茎”、“叶”等部件在内,不能也不需要再和这些部件并列。

在类级别,说“植物和根、茎、叶是整体-部分关联”,可以。

在对象级别,说“某个植物对象由若干根、茎、叶对象组成”,可以。

但是,说“某个植物对象和它的根、茎、叶一起组成aggregate”,不可以。

说“植物对象是一个aggregate”,可以,但这样的说法无意义。所有对象都是aggregate,否则要它干什么呢?

要把这个圆过去,可以把“植物”排除在组成aggregate的“一簇相关联的对象”之外,说“一簇根、茎、叶对象组成了植物aggregate”,不过,Eric Evans又说了“根是AGGREGATE的成员”,看来是圆不过去了。

再来看②的问题。

即使我们排除了①的错误,采取“一簇根、茎、叶对象组成了植物aggregate”的说法,但说法②仍然不合适。我们可以看下面的表述:

植物由根、茎、叶组成,所以,植物是[根……]的根?

汽车由发动机、车身、底盘组成,所以,汽车是[发动机……]的根?

墙由砖垒成,所以,墙是砖的根?

分子由原子组成,所以,分子是原子的根?

之所以会有aggregate root这样的错觉,有可能是受了关系数据库思考方式的影响。

图8-139的类图,如果用关系数据库来保存对象,可能会得到图8-145的几个表,这样就产生了“植物”就是“植物”表的错觉,于是觉得有必要提醒它是aggregate root,别忘了带上其他几个小弟。

图片

图8-145 受关系数据库思考方式影响的aggregate root错觉

aggregate root错觉另一个可能的原因来自人类社会的直觉。

(待续……)

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

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

相关文章

04--SpringBoot热部署与日志

1、热部署 1.1 引言 为了进一步提高开发效率,SpringBoot为我们提供了全部项目热部署,日后在开发过程中修改了部分代码或者相关配置文件之后,不需要再重启服务使其生效。在项目中开启了全局热部署之后,只需要在修改之后等待几秒钟…

气密检测中泄漏率的质量流量与体积流量的转换

对于R-134a等制冷剂,泄漏率通常表示为质量流量(每年的逸出质量)而不是体积流量(特定时间段内给定压力下的逸出质量)。因此,通过制冷剂的年泄漏量来定义泄漏级别,常用的单位为g/a。以某款车型为例…

Github 2024-05-29 C开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-29统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10C++项目3PHP项目1PHP:流行的Web开发脚本语言 创建周期:4710 天开发语言:C, PHP协议类型:OtherStar数量:37340 个Fork数量:7657 次…

从 0 手撸一个 pytorch

背景介绍 最近抽空看了下 Andrej Karpathy 的视频教程 building micrograd,教程的质量很高。教程不需要任何前置机器学习基础,只需要有高中水平的数学基础即可。整个教程从 0 到 1 手撸了一个类 pytorch 的机器学习库 micrograd,核心代码不到…

SAP PP学习笔记 - 错误 CX_SLD_API_EXCEPTION - Job dump is not fully saved (too big)

我这个错误是跑完MRP,然后在MD04查看在库/所有量一览, 点计划手配(Planned order 计划订单)生成 制造指图(Production order 生产订单), 到目前这几步都OK,然后在制造指图界面点保…

Linux之sshpass命令

介绍 sshpass是一个工具,用于通过SSH连接到远程服务器时自动输入密码。它允许您在命令行中指定密码,以便在建立SSH连接时自动进行身份验证。 安装 # 以centos为例 yum install sshpass -y 使用方法 sshpass [-f filename | -d num | -p password | …

C++笔试强训day35

目录 1.奇数位丢弃 2.求和 3.计算字符串的编辑距离 1.奇数位丢弃 链接https://www.nowcoder.com/practice/196141ecd6eb401da3111748d30e9141?tpId128&tqId33775&ru/exam/oj 数据量不大&#xff0c;可以直接进行模拟&#xff1a; #include <iostream> #incl…

MQTT 5.0 报文解析 06:AUTH

欢迎阅读 MQTT 5.0 报文系列 的最后一篇文章。在上一篇中&#xff0c;我们已经介绍了 MQTT 5.0 的 DISCONNECT 报文。现在&#xff0c;我们将介绍 MQTT 中的最后一个控制报文&#xff1a;AUTH。 MQTT 5.0 引入了增强认证特性&#xff0c;它使 MQTT 除了简单密码认证和 Token 认…

没有可用软件包 docker-ce。 错误:无须任何处理

特么的各种百度查看&#xff0c;全是一些废话&#xff01;&#xff01;&#xff01;centos7安装不上docker&#xff0c;都是老的代码了&#xff1a; yum install docker-ce 解决方案&#xff1a; # CentOS yum install docker-io

Jetson Orin Nano v6.0 + tensorflow2.15.0+nv24.05 GPU版本安装

Jetson Orin Nano v6.0 tensorflow2.15.0nv24.05 GPU版本安装 1. 源由2. 步骤2.1 Step1&#xff1a;系统安装2.2 Step2: nvidia-jetpack安装2.3 Step3&#xff1a;jtop安装2.4 Step4&#xff1a;h5py安装2.5 Step5&#xff1a;tensorflow安装2.6 Step6&#xff1a;jupyterlab安…

Windows搭建Nginx代理本地盘的文件(共享路径或本地路径)

文章目录 Windows搭建Nginx代理本地盘的文件 - 前言需求背景挂载网络共享路径检查连接状态下载Nginx编辑 Nginx 配置文件启动 Nginx检测Nginx是否成功启动使用方法远程共享路径示例本地文件示例 测试 Windows搭建Nginx代理本地盘的文件 - 前言 在开发过程中&#xff0c;确保文…

广东省保健食品行业协会批复成为“世界酒中国菜”活动指导单位

广东省保健食品行业协会正式批复成为“世界酒中国菜”系列活动指导单位&#xff0c;共促餐饮文化交流发展 近日&#xff0c;广东省保健食品行业协会正式批复荐酒师国际认证&#xff08;广州&#xff09;有限公司&#xff0c;成为备受瞩目的“世界酒中国菜”系列活动的指导单位…

8.2 数组遍历访问

本节必须掌握的知识点&#xff1a; 示例三十 代码分析 汇编解析 在上一节中介绍了数组相关的概念&#xff0c;而在本节中将介绍数组的使用。 8.2.1 示例三十 ■访问数组 示例代码三十 ●第一步&#xff1a;分析需求&#xff0c;设计程序…

基于C++11实现的手写线程池

在实际的项目中&#xff0c;使用线程池是非常广泛的&#xff0c;所以最近学习了线程池的开发&#xff0c;在此做一个总结。 源码&#xff1a;https://github.com/Cheeron955/Handwriting-threadpool-based-on-C-17 项目介绍 项目分为两个部分&#xff0c;在初版的时候&#x…

STM32——定时器

一、简介 *定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断 *16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时 *不仅具备基本的定时中断功能&#xff0c;而且还包含内外时钟源选择、输入…

ubuntu使用oh my zsh美化终端

ubuntu使用oh my zsh美化终端 文章目录 ubuntu使用oh my zsh美化终端1. 安装zsh和oh my zsh2. 修改zsh主题3. 安装zsh插件4. 将.bashrc移植到.zshrcReference 1. 安装zsh和oh my zsh 首先安装zsh sudo apt install zsh然后查看本地有哪些shell可以使用 cat /etc/shells 将默…

平方回文数-第13届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第73讲。 平方回文数&#…

监控云安全的9个方法和措施

如今&#xff0c;很多企业致力于提高云计算安全指标的可见性&#xff0c;这是由于云计算的安全性与本地部署的安全性根本不同&#xff0c;并且随着企业将应用程序、服务和数据移动到新环境&#xff0c;需要不同的实践。检测云的云检测就显得极其重要。 如今&#xff0c;很多企业…

windows tomcat服务注册和卸载

首页解压tomcat压缩包&#xff0c;然后进入tomcat bin目录&#xff0c;在此目录通过cmd进入窗口&#xff0c; 1&#xff1a;tomcat服务注册 执行命令&#xff1a;service.bat install tomcat8.5.100 命令执行成功后&#xff0c;会在注册服务列表出现这个服务&#xff0c;如果…

打造爆款活动:确定目标受众与吸引策略的实战指南

身为一名文案策划经理&#xff0c;我深知在活动策划的海洋中&#xff0c;确定目标受众并设计出能触动他们心弦的策略是何等重要。 通过以下步骤&#xff0c;你可以更准确地确定目标受众&#xff0c;并制定出有效的吸引策略&#xff0c;确保活动的成功&#xff1a; 明确活动目…