Value vs Entity objects (Domain Driven Design)

I have just started reading DDD. I am unable to completely grasp the concept of Entity vs Value objects.. Can someone please explain the problems (maintainability, performance.. etc) a system could face when a Value object is designed as a Entity object? Example would be great...

44378 次浏览

归结为本质区别,身份对实体很重要,但对价值对象不重要。例如,某人的 Name 是一个值对象。Customer 实体可能由 Customer Name (值对象)、 List < Order > OrderHistory (实体列表)和默认 Address (通常是值对象)组成。Customer Entity 将有一个 ID,并且每个订单都将有一个 ID,但 Name 不应该有; 通常,在对象模型中,Address 的标识可能并不重要。

值对象通常可以表示为不可变对象; 更改值对象的一个属性实际上会破坏旧对象并创建一个新对象,因为您不像关心内容那样关心标识。只要对象的属性与另一个实例的属性相同,Name 上的 Equals 实例方法就会正确地返回“ true”。

但是,更改类似 Customer 的实体的某些属性并不会破坏客户; Customer 实体通常是可变的。标识保持不变(至少在对象被持久化之后)。

您可能在没有意识到的情况下创建了值对象; 当您通过创建一个细粒度类来表示 Entity 的某个方面时,您就得到了一个值对象。例如,类 IPAddress 将是一个值对象,它对有效值有一些约束,但是由更简单的数据类型组成。EmailAddress 可以是一个字符串,也可以是一个具有自己行为集的值对象。

甚至在数据库中具有标识的项在对象模型中也很可能没有标识。但最简单的情况是将一些有意义的属性组合在一起。你可能不想要顾客。顾客姓名。姓氏,顾客。中间首字母和客户。标题当你可以组成这些一起作为客户。在考虑持久性时,它们可能是数据库中的多个字段,但是对象模型并不关心这一点。

我不知道下面的内容是否正确,但我想说的是,在 Address 对象的情况下,我们希望使用它作为值对象而不是实体,因为对实体的更改将反映在所有链接对象(例如 Person)上。

举个例子: 你和其他人一起住在你的房子里。如果我们使用 Entity for Address,我认为所有 Person 对象都会链接到一个惟一的 Address。如果一个人搬出去了,你要更新他的地址。如果您要更新地址实体的属性,所有人都将拥有不同的地址。对于 Value 对象,我们将无法编辑 Address (因为它是不可变的) ,并且将被迫为该 Person 提供一个新的 Address。

Does this sound right? I must say that I was/am also still confused about this difference, after reading the DDD book.

更进一步,这将如何在数据库中建模?您是将 Address 对象的所有属性作为 Person 表中的列,还是创建一个单独的 Address 表,该表也有一个唯一标识符?在后一种情况下,住在同一所房子里的每个人都有一个不同的 Address 对象实例,但是除了他们的 ID 属性之外,这些对象是相同的。

所有属性共同定义的任何对象都是值对象。如果任何属性发生更改,则有一个值对象的新实例。这就是为什么值对象被定义为不可变的。

如果对象没有完全由其所有属性定义,那么就有一个属性子集构成对象的标识。其余的属性可以在不重新定义对象的情况下进行更改。这种类型的对象不能在不可变条件下定义。

区分的一个简单方法是将值对象视为永远不会更改的静态数据,将实体视为在应用程序中发展的数据。

我在另一个帖子里问过这个问题,我想我还是很困惑。我可能把性能考虑和数据建模混淆了。在我们的编目应用程序中,客户只有在需要时才会更改。这听起来很愚蠢——但是客户数据的“读取”远远超过了“写入”,而且由于许多网络请求都碰到了对象的“活动集”,所以我不想一次又一次地加载“客户”。因此,我为 Customer 对象走上了一条不可改变的道路——加载它,缓存它,并为99% 的(多线程)希望查看 Customer 的请求提供相同的服务。然后,当客户更改某些内容时,让一个“编辑器”生成一个新的 Customer,并使旧的 Customer 无效。

我担心的是,如果许多线程看到相同的客户对象,并且它是可变的,那么当一个线程开始更改时,其他线程就会受到损害。

我现在的问题是: 1)这是否合理; 2)如何在不复制大量关于属性的代码的情况下最好地完成这项工作。

地址可以是依赖于业务流程的实体或值对象。地址对象可以是快递应用程序中的实体,也可以是其他应用程序中的值对象。在信使应用程序的地址对象的身份事项

3区分 EntitiesValue Objects

  • 标识符与结构相等: 实体具有标识符,如果实体具有相同的标识符,则它们是相同的 标识符。 值对象超出手的结构相等,我们考虑两个 当所有字段相同时,值对象相等 有标识符。

  • 可变性与不可变性: Value Objects are immutable data structures whereas entities change during 他们的一生

  • 生命周期: 值对象应该属于实体

Value Types :

  • Value types do not exist on his own, depends on Entity types.
  • 值类型对象属于实体类型对象。
  • 值类型实例的生命周期受所属实体实例的生命周期的限制。
  • Three Value types: Basic(primitive datatypes), Composite(Address) and Collection(Map, List, Arrays)

实体:

  • Entity types can exist on his own (Identity)
  • An entity has its own life-cycle. It may exist independently of any other entity.
  • 例如: 人,组织,学院,移动,家等等。每个对象都有自己的身份

用一句简单的话来说,我们有三种类型的平等:

  • 标识符相等 : 一个类具有 id 字段,并将两个对象与它们的 id 字段值进行比较。
  • 引用相等 : 如果对两个对象的引用在内存中有相同的地址。
  • 结构相等 : 如果两个对象的所有成员都匹配,则两个对象相等。

标识符等式 refers仅表示实体,结构等式仅表示值对象。事实上,值对象没有 id,我们可以互换地使用它们。而且值对象必须是不可变的,实体可以是可变的,值对象在数据库中没有任何表。

为了更好地理解值对象和实体之间的区别,请考虑来自 维基百科的以下示例:

价值对象: 当人们兑换美元钞票时,他们通常不会这样做 区分每一张独特的钞票; 他们只关心脸 在这情况下,美元钞票是价值对象, 美联储可能会关心每一个独特的法案; 在这种情况下,每一个 法案将是一个实体。

大多数航空公司对每个航班的每个座位都有独特的区别 然而,西南航空公司、易捷航空公司和瑞安航空公司 not distinguish between every seat; all seats are the same. In this context, a seat is actually a Value Object.