DDD:带 Id 的值对象

问题描述 投票:0回答:1

我有一个关于 DDD 测试聚合中的 1 个“类”是否构成值对象或实体的问题。

假设我有 2 个聚合:

  1. 测试定义
  2. 测试

Test 包含 TestDefinition 的链接。现在,在正常情况下,只需在测试上添加 TestDefinitionId 就足够了,但是我想在测试上存储 TestDefinition 的快照(就像在测试创建时一样)。

这个快照是不可变的(就像值对象通常一样),但理论上包含一个 Id(就像实体通常那样)。然而我觉得这个 Id 更偶然(并且为了完整性)。我本可以很容易地删除 ID,而且不会产生任何后果。

所以我的问题是,TestDefinition(在我的测试聚合的上下文中)是 ValueObject 还是实体? (如果是这样,你的理由是什么)

domain-driven-design aggregateroot
1个回答
0
投票

在领域驱动设计(DDD)中,实体和值对象之间的区别很重要,有时可能很细微。让我们分解您的场景,以确定

TestDefinition
聚合中
Test
的快照是否应被视为值对象或实体。

实体和值对象的主要特征:

实体:

  1. 身份:实体具有贯穿时间和不同状态的独特身份。它们通过唯一的 ID 进行识别。
  2. 生命周期:实体通常有生命周期,它们的状态可以随着时间的推移而改变。
  3. 可变性:实体通常是可变的,这意味着它们的状态可以随着系统的发展而改变。

值对象:

  1. 无身份:值对象没有明确的身份。它们由它们的属性定义,如果它们的属性相同,则被认为是相等的。
  2. 不可变性:值对象通常是不可变的,这意味着它们的状态一旦创建就无法更改。
  3. 平等:值对象根据其属性而不是任何身份进行比较。

TestDefinition
背景下分析
Test
聚合:

  1. 不变性:您提到

    TestDefinition
    的快照在
    Test
    聚合内是不可变的。这强烈表明它可能是一个值对象,因为不变性是值对象的核心特征。

  2. 身份存在:尽管快照包含 ID,但您表示该 ID 是偶然的,可以删除而不会产生任何后果。这表明身份对于快照在

    Test
    聚合中的作用并不重要。

  3. 聚合内的用途:快照的目的是捕获

    TestDefinition
    在创建
    Test
    时的状态。这个历史快照旨在代表状态,而不是持续的身份。值对象通常可以很好地满足此目的,因为它们捕获和传达状态,而不用担心随着时间的推移会有唯一的身份。

结论:

根据您的描述,在

Test
聚合的上下文中,
TestDefinition
的快照最好归类为 值对象。原因如下:

  • 不变性:快照一旦创建就不会更改。
  • 状态表示:快照捕获特定时间点
    TestDefinition
    的状态。
  • 意外身份:快照中的 ID 是偶然的,对于其在
    Test
    聚合中的角色来说并不是基础。

ID 的存在并不一定使对象成为实体,特别是如果 ID 不用于以有意义的方式将对象与其他实例区分开来。由于快照中的 ID 在聚合中的识别中并不发挥关键作用,因此它更符合值对象的特征。

© www.soinside.com 2019 - 2024. All rights reserved.