聚合中的实体没有身份?
Entity in Aggregate Without Identity?
我一直在努力思考领域驱动的设计概念,我一直回想的一个问题是如何处理我通常会使用可变 class 实现但没有实现的功能'在域中没有自己的身份。
示例域
假设我们有一个 Game Board 实体,负责更新简单棋盘游戏(如国际象棋)中各种标记的位置。我们还假设玩家根据他们玩游戏的时间进行评分,不包括游戏暂停的任何时间。更新经过时间和更新游戏板的逻辑是完全不同的,所以我们创建一个 Timer class 来封装存储和计算游戏时间的功能。最后,我们希望在游戏暂停时禁止更新 Game Board,并希望确保 Timer 在游戏暂停时 paused/resumed游戏是 paused/resumed,因此我们创建一个 Game 聚合,其中包含一个 Game 实体,该实体通过提供自己的 pause/resume/move 来强制执行这些不变量包装对底层 Timer 和 Game Board 方法的调用的方法(并且不允许外部访问这些对象的方法来改变它们的状态).
问题
Timer 和 Game Board 在此示例中都是可变的,并且具有驱动其状态变化的复杂业务逻辑,因此感觉不对只需将他们的逻辑与 Game 的逻辑结合起来;此外,一个 Game 只会有一个 Timer 和一个 Game Board 专门属于那个特定的实例,所以这两个对象似乎并没有真正拥有自己的身份。这两个对象中的任何一个都存在于它们的 Game.
之外也没有意义
问题
可以公平地说 Timer 和 Game Board 只是隐式具有与 [=26= 相同身份的实体]Game 持有它们(表示每个 Game 只能存在一个实例)?如果是这样,代表这些实体的这些 classes 是否真的需要保存对其聚合的游戏 ID 的引用(假设这是游戏的身份),或者它们在聚合中的存在是否可以将它们与其关联起来?
如果不是,是否有我遗漏的东西可以解决这个问题而不只是将所有三个概念合二为一?
实体需要 Id 的原因有两个(关于您的设计)。
- 游戏对象需要在不比较其内容的情况下区分多个相同实体类型的实例。
- 您的 ORM 或数据库系统要求您在您持久保存的每个数据对象中都有一个 Id。
如果你不需要以上两个中的任何一个(并且你不需要第1点),那么Entity就不需要有Id。
如果你问,从 DDD 的角度来看这个概念如何,我的想法是这样的:领域驱动设计,在实现层面上,不关心实体,它们甚至不是在许多情况下无处不在的语言。它们只是一个有助于将大型 AR 分解为更小、更具凝聚力的部分的概念。
我制作了很多系统,它们甚至聚合了具有相同 Id 和类型后缀的根。在关系数据库中,您可以在两个主键上创建一个外键,有效地在表之间创建一对一关系,从我的角度来看这是完全有效的。
我一直在努力思考领域驱动的设计概念,我一直回想的一个问题是如何处理我通常会使用可变 class 实现但没有实现的功能'在域中没有自己的身份。
示例域
假设我们有一个 Game Board 实体,负责更新简单棋盘游戏(如国际象棋)中各种标记的位置。我们还假设玩家根据他们玩游戏的时间进行评分,不包括游戏暂停的任何时间。更新经过时间和更新游戏板的逻辑是完全不同的,所以我们创建一个 Timer class 来封装存储和计算游戏时间的功能。最后,我们希望在游戏暂停时禁止更新 Game Board,并希望确保 Timer 在游戏暂停时 paused/resumed游戏是 paused/resumed,因此我们创建一个 Game 聚合,其中包含一个 Game 实体,该实体通过提供自己的 pause/resume/move 来强制执行这些不变量包装对底层 Timer 和 Game Board 方法的调用的方法(并且不允许外部访问这些对象的方法来改变它们的状态).
问题
Timer 和 Game Board 在此示例中都是可变的,并且具有驱动其状态变化的复杂业务逻辑,因此感觉不对只需将他们的逻辑与 Game 的逻辑结合起来;此外,一个 Game 只会有一个 Timer 和一个 Game Board 专门属于那个特定的实例,所以这两个对象似乎并没有真正拥有自己的身份。这两个对象中的任何一个都存在于它们的 Game.
之外也没有意义问题
可以公平地说 Timer 和 Game Board 只是隐式具有与 [=26= 相同身份的实体]Game 持有它们(表示每个 Game 只能存在一个实例)?如果是这样,代表这些实体的这些 classes 是否真的需要保存对其聚合的游戏 ID 的引用(假设这是游戏的身份),或者它们在聚合中的存在是否可以将它们与其关联起来?
如果不是,是否有我遗漏的东西可以解决这个问题而不只是将所有三个概念合二为一?
实体需要 Id 的原因有两个(关于您的设计)。
- 游戏对象需要在不比较其内容的情况下区分多个相同实体类型的实例。
- 您的 ORM 或数据库系统要求您在您持久保存的每个数据对象中都有一个 Id。
如果你不需要以上两个中的任何一个(并且你不需要第1点),那么Entity就不需要有Id。
如果你问,从 DDD 的角度来看这个概念如何,我的想法是这样的:领域驱动设计,在实现层面上,不关心实体,它们甚至不是在许多情况下无处不在的语言。它们只是一个有助于将大型 AR 分解为更小、更具凝聚力的部分的概念。
我制作了很多系统,它们甚至聚合了具有相同 Id 和类型后缀的根。在关系数据库中,您可以在两个主键上创建一个外键,有效地在表之间创建一对一关系,从我的角度来看这是完全有效的。