DDD:聚合的聚合

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

为了练习 DDD,我正在尝试构建一个简单的餐厅网站。我试图了解何时应该应用聚合以及应用程序限制(如果有)是什么。

域名

传说如下:我们有几个地方(连锁餐厅?)的菜单略有不同但交叉。我们希望有一个网站公开该菜单(计划稍后添加在线订购)。

我正在尝试对以下一组实体进行建模:

  • 餐厅
  • 菜单
  • 菜单类别
  • 菜单项

在我看来,每个连接都应该是一个组合(用 UML 术语来说):

  • 餐厅拥有菜单(一份有效的菜单,一些未来的草稿,菜单历史列表)。我们不想在餐厅之外管理它们。如果餐厅被删除,其所有菜单也应被删除。只能编辑草稿菜单;
  • 菜单拥有一组类别,维护它们的顺序,只读时不允许更改任何内容,具有删除级联;
  • 菜单类别又对菜单项执行相同的操作。

在我看来,菜单项不会在菜单中重复使用。菜单项是某种快照,一旦菜单被激活,它就变得不可变。

问题

在我对 DDD 的阅读中,我没有看到超过一层的聚合。在这些示例中,一个聚合可以引用另一个聚合,但我没有看到嵌套聚合。

  1. 我是否正确理解了何时在 DDD 中使用聚合?或者也许我应该拥有单独的实体?
  2. 多级聚合可以吗?这被认为是不好的做法吗?也许这意味着未来会遇到一些困难?

将欣赏有关该主题的一些好的读物/视频/播客。 谢谢!

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

AGGREGATE 是一组关联对象,我们将其视为一个单元以进行数据更改。 (领域驱动设计:解决软件核心的复杂性,第 6 章)

AGGREGATE 与粗粒度锁非常相似(摘自企业应用架构模式

聚合的特性需要粗粒度锁,因为使用其任何成员都需要锁定所有成员。

因此,嵌套聚合变得有点奇怪:聚合 B 中的聚合 A 中有一些实体 e。当您想要更改 e 时,您“需要”锁定 A(因为 e 是 A 的成员),并且你“需要”锁定 B(因为 e 通过组合成为 B 的成员),如果你总是需要同时获取锁 A 和锁 B,那么锁 A 实际上做了什么有用的事情吗?

聚合的真正动机是让人们更容易地生成和维护模型。嵌套聚合似乎不符合该规则。

用另一种方式表达:嵌套聚合表明您的聚合边界与问题域的实际需求之间存在阻抗不匹配,您可能应该解决这个问题,而不是尝试让嵌套“工作”。

“删除”对于理解聚合来说往往是一个糟糕的启发式(参见Udi Dahan 2009),部分原因是它不能很好地代表业务中正在发生的事情(关闭一家餐馆与摧毁所有餐厅是一个非常不同的想法)餐厅记录)。

相反,要注意信息如何变化,以及哪些类型的变化应该能够相互独立地发生。例如,一家餐馆的名称历史、一家餐馆老板的历史以及一家餐馆菜单的历史——将这些合并到一个集合中真的会对您有利吗?还是对它们进行处理会更好?具有自己的锁的单独聚合?

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