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

news2024/11/16 9:57:03

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错觉另一个可能的原因来自人类社会的直觉。

(待续……)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「光储充放」一体充电站-一文读懂光储充放充电站

“光储充放”一体充电站作为一种储能充电的新形式渐渐走进人们的生活,全国很多地区都开始陆续投放运营“光储充放”一体充电站,今天的这篇文章,就带大家全面了解“光储充放”这一新型充电站。 头图来源 | 视觉中国 01 政策背景 早在2020年…

43-2 Linux入侵排查实验

环境准备: 老规则,我没有靶场就自己搭建了类似, 这里准备一台CentOS 7虚拟机作为受害者,然后使用CS制作木马并在受害者主机上线,具体过程可以看我之前写的一篇文章: 黑客必备利器:如何在系统上安装和使用 CobaltStrike(简称:CS)_cobalt strike-CSDN博客 最终的效果…

【ARFoundation自学03】AR Point Cloud 点云(参考点标记)功能详解

和平面识别框架一样 1为XR Origin添加AR Point Cloud Manager组件 然后你的ar应用就具备了点云识别功能,就这么简单 2.可视化这些云点 创建一个美术效果的预制体,人家提供了预设模板 然后拖到仓库(ASSETS)创建预制体&#xff…

红酒与不同烹饪方法的食物搭配原则

红酒与食物的搭配是一门艺术,而不同烹饪方法的食物与红酒的搭配也有其与众不同之处。红酒与食物的搭配不仅涉及到口感、风味和营养,还与烹饪方法和食物质地等因素息息相关。云仓酒庄雷盛红酒以其卓着的品质和丰富的口感,成为了实现完善搭配的…

常用压力、流量单位换算表

一、压力为单位面积所承受的力 压力:绝对压力 、表压力 、大气压力。相互关系:绝对压力表压力大气压力 绝对压力:当压力表示与完全真空的差。测量处的实际压力。 表压力:当表示其气体数值与该地域大气压力的差值。 大气压力:由大气重量所…

JAVA学习·String类的常用方法

String 类及其创建 String 类的创建 String 类是 Java 内置的一个类,其完全限定类名是java.lang.String。想要创建一个字符串有多重方式,比如创建字符串"Hello": String s1 "Hello"; // 字面量创建 String s2 new St…

IDEA升级web项目为maven项目乱码

今天将一个java web项目改造为maven项目。 首先&#xff0c;创建一个新的maven项目&#xff0c;将文件拷贝到新项目中。 其次&#xff0c;将旧项目的jar包&#xff0c;在maven的pom.xml做成依赖 接着&#xff0c;把没有maven坐标的jar包在编译的时候也包含进来 <build>…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 5月29日,星期三

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年5月29日 星期三 农历四月廿二 1、 首个未成年人游戏退费标准发布&#xff1a;监护人与网游服务提供者将按错担责。 2、 六部门联合印发通知&#xff1a;鼓励加快高清超高清电视机等普及、更新。 3、 神舟十八号航天员乘…

Rocksdb原理简介

100编程书屋_孔夫子旧书网 Rocksdb作为当下nosql中性能的代表被各个存储组件&#xff08;mysql、tikv、pmdk、bluestore&#xff09;作为存储引擎底座&#xff0c;其基于LSM tree的核心存储结构&#xff08;将随机写通过数据结构转化为顺序写&#xff09;来提供高性能的写吞吐时…

上海亚商投顾:沪指冲高回落 电力、电网产业链持续爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日震荡调整&#xff0c;深成指、创业板指均跌超1%。电力、电网股再度爆发&#xff0c;众智科技、郴电国…

Post Microsoft Build and AI Day 上海开发者日

点击蓝字 关注我们 编辑&#xff1a;Alan Wang 排版&#xff1a;Rani Sun 这个六一怎么过&#xff1f;来微软 Reactor&#xff0c;一起过儿童节吧&#xff01; 6月1日&#xff0c;Microsoft Azure & Microsoft Reactor 面向大小朋友特别推出六一特辑&#xff0c;「Post Mic…

Django配置

后端开发&#xff1a; python 解释器、 pycharm 社区版、 navicate 、 mysql(phpstudy) 前段开发&#xff1a; vs code 、 google 浏览器 django 项目配置 配置项目启动方式 创建模型 创建一个应用 在应用中创建模型类 根据模型类生成数据表 创建应用 创建模型类 …

Ps:使用消失点滤镜进行透视贴图

可以在“消失点”滤镜中粘贴 Photoshoop 剪贴板中的图像。 拷贝的贴图可以来自于同一文档或不同文档&#xff0c;但不能是矢量图形。 比如&#xff0c;如果要将文字图层作为贴图&#xff0c;必须先将其栅格化。 一旦粘贴到“消失点”滤镜中&#xff0c;贴图将变为浮动选区&…

量子密钥分发系统基础器件(一):光纤干涉仪

干涉仪的基本原理是利用波的叠加来获得波的相位信息&#xff0c;从而获取实验中所关心的物理量。光纤干涉仪是由光学干涉仪发展而来的&#xff0c;利用光纤实现光的干涉&#xff0c;由于光纤取代透镜系统构成的光路具有柔软、形状可随意变化、传输距离远等特点&#xff0c;当前…

04--SpringBoot热部署与日志

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

数据库(9)——DQL基础查询

数据查询 数据查询是SQL中最复杂的&#xff0c;语法结构为 SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVING 分组后字段列表 ORDER BY 排序字段列表 LIMIT 分页参数 查询多个字段 SELECT 字段1&#xff0c;字段2...FROM…

sysbench安装(在线离线)

简介 sysbench是一个多线程基准测试工具&#xff0c;它支持硬件&#xff08;CPU、内存、I/O&#xff09;、数据库基准压测等2种测试手段&#xff0c;用于评估系统的基本性能。本篇文章主要介绍sysbench在线和离线2种安装方法&#xff0c;并将离线编译时发生的异常记录到FAQ&…

LES物流执行系统,在离散制造行业有那些作用和价值?

离散制造企业往往面临的是多品种、小批量的非标订单生产&#xff0c;传统推动式物流系统已经无法应对计划变化滞后&#xff0c;各车间、工序之间难以衔接等情况&#xff0c;特别是密集劳动力的电子行业&#xff0c;非标产品 SKU 种类繁多&#xff0c;物料配送复杂&#xff0c;对…

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

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

基于springboot+vue的社区医院管理服务系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…