实体和聚合之间的UML区别是什么?

3
从我阅读的一篇文章中得知,实体只是聚合的一个子集。我已经在领域驱动设计实现领域驱动设计中阅读了这两种模式的相关内容,并试图理解它们之间的UML差异。
让我们考虑一个简单的类。它是一个信件,包含消息、接收者和可能的发送者。

enter image description here

我猜这个Letter类会被视为一个实体?
现在假设我们想扩展我们的包裹业务,使其也能够发送包裹,那么它可能会像下面这样。

enter image description here

由于如果整个包被丢失,包中的所有项目都将丢失,因此我们使用 UML 组合关系(一个填充的菱形)。我们还希望通过禁止从包外更改或删除项目来保持包的一致性。聚合描述如下:

聚合根通过禁止外部对象持有其成员的引用来保证在聚合内进行的更改的一致性。

因此,我们确保组合关系在聚合内部隐藏,并保留不变量。
我的问题是:
我们是否可以说 Entity 和 Aggregate 之间的 UML 差异在于 Entity 不包含任何组合关系,而 Aggregate 至少包含一个组合关系?

"实体"是UML的一个关键字,其含义与一般IT上下文中的含义基本相同。它是应用于组件的预定义标准构造。在UML文档中,其语义被给定为“标准构造:L2(业务概念)”。(L2仅表示符合等级2;UML系统配置文件有3个符合等级。) - BobRodes
1
提示:除非您希望发送空包裹,否则Item的多重性值应为1..*。此外,由于您没有零个或多个发件人,因此您的发件人应该只有1。 - BobRodes
@BobRodes 很好的观点。我添加了关系,从需要在包中提供哪些信息的角度来看,而不是执行方式的角度。 - Daniel
@BobRodes,Item的0..*多重性与最初绘制的一样是正确的。一个Package可以存在于内存或场景中,而没有Items。Package不能没有Items进行发货是一个业务规则。 - aryeh
好的,如果您对问题域中的业务规则有内部了解,那么我不会像这样设置业务规则。我的规则是:没有物品,包裹就不能存在于系统中。 - BobRodes
3个回答

2
回答你的问题,不可以这样说。聚合根是实体本身,可能由子实体组成,也可能不是。子实体也可以由其他实体组成(虽然通常不建议这样做)。
聚合根负责维护其自身和其子实体的状态并强制执行不变量。
因此,总结一下,一个聚合和一个子实体都可以有0个或多个子实体。但所有子实体都需要一个聚合根。

你说得对。聚合根的工作方式类似于实体,因为它不需要具有任何组合关系。然而,据我所知,子实体并不需要聚合根。至少从Evans,p.94,Figure 5.5来看是这样的。 - Daniel
你是在说一个子实体由其他子实体组成的情况吗?虽然这些子子实体可能与聚合体没有直接关联,但它们仍然是聚合根的一部分并受其控制。如果你说子实体可以完全存在于聚合根之外,那我还没有听说过。 - Tyler Day
好的,它是这样工作的吗?聚合根是客户端唯一接触到的对象。聚合不是一个对象本身,而是一个概念,其中聚合= 1聚合根+ N实体+ N值对象。实体永远不会被客户直接使用,因为它们非常容易暴露并且未受不变量保护。相反,实体在构建聚合时作为构建块使用,其中聚合根保留所有不变量。 - Daniel
接近了,但聚合根本身也是一种实体。例如,你可以有一个名为“客户”的AR,它完全没有任何子实体。因此,一个聚合根可以有零个或多个子实体/值对象。 - Tyler Day
好的,太棒了!谢谢 Tyler! - Daniel

1
实体表示MVC中的模型。通常表示为<<entity>>构造的类。
聚合是聚合不同其他类的类的同义词。这意味着它需要其他类来维持其生命周期。还有一个组合,它类似于聚合,但相关的类实例将随着组合类一起消失。
回答最后一个问题:实体是原子的。它没有聚合任何内容。
编辑自从我为我的工作遇到它以来:有实体组成/聚合其他实体。30年前在大学时我们称它们为梯形因为它们悬挂在两个其他实体之间并联系它们。现在我会称它们为关联类。

2
参见 uml-diagrams.org: 类图 → 类 → 非标准类别 → «实体»。在我看来,实体是指拥有自己数据库表的事物。其余关系和属性则属于另一个层次的问题。 - xmojmr
是的,这就是我要确认的。实体最终会转化为数据库表。 - qwerty_so
感谢您的回复!我猜您的答案是严格基于UML的。据我所知,DDD中没有组合模式。这就是我试图搞清楚的事情;DDD模式与UML之间的关系如何。 - Daniel
需要一点时间才能弄清楚DDD的含义。是的,我的答案基于UML。我不知道这本书,但猜测它也建立在UML之上? - qwerty_so

0
在领域驱动设计(DDD)中,实体只是UML术语中的类别。这个类别告诉你该对象是通过显式唯一标识符来标识的,而不是通过其属性来标识。
对象模型中的对象相互协作,它们一起形成对象图。聚合表示一组需要一起考虑的对象,因为如果不这样做,可能会导致其中一个或多个对象处于无效状态。
“我们可以说UML中的Entity和Aggregate之间的区别是,Entity不包含任何组合关系,而Aggregate至少包含一个组合关系吗?”不行。UML中的组合或聚合关联与DDD的聚合或实体的概念无关。
例如,可以在UML中表示Transaction-LineItem的关系,而不使用组合或(UML)聚合。
Transaction --- 1 -------- 0..* --- LineItem
如上所述,以上两个对象都需要成为相同的(DDD)聚合的一部分,因为它们需要被视为一对。如果单独处理它们,则可能会使它们的组合状态无效或不正确。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接