DDD 中的有效聚合根设计(Vernon 的解释)

Effective aggregate root design in DDD (Vernon's explanations)

我有一个关于聚合设计的问题,正如 Vernon 在他在 DDD 社区 (Effective Aggregate Design, Part 3) 的文章和他的书(实施领域驱动设计)中所提出的那样。

在那里,他在设计 BacklogItemTask 时探索了两种可能的方法。其中一个任务不是它自己的聚合根,因为它运行 "risk of leaving the true invariant unprotected",聚合根是 BacklogItem

但是,设计聚合根的其他准则之一是对实体的访问只能通过根本身完成。这意味着为了在这种方法中获得对 Task 的访问权限,现在必须访问它所属的 BacklogItem 并请求积压项目。通常,虽然人们只想看到 Tasks 被分配,而不是积压项目。

在这种情况下,我们需要直接访问实体,而不是通过 Backlog 项。这与提议的设计有何关系? (我知道这可能只是一个教育演示,但如果这是现实生活,人们会怎么想呢?)

提前感谢您的回答

In this case we will need to access the entity directly and not via the Backlog item. How does this sit with the proposed design?

这取决于:"access directly" 未指定。

Bertrand Mayer 的 command query separation 语言在这里有所帮助。查询保持模型不变;命令更新模型。

这是关键思想:聚合根的唯一关注点是命令;聚合状态的任何更改都是通过向根实体发送命令来实现的,根实体可以自行决定将更改状态的责任委托给其他实体。

因此,如果您正在访问任务以查询其当前状态,那很好。但是获取任务以便您可以直接向它发送命令?那违反了规则。聚合根具有独占访问聚合内所有实体命令的特权。

这意味着您永远不会直接调用 Task.estimateRemainingHours();您将改为在聚合根上调用一些类似的方法。 BacklogItem.logEstimateFromTeamMember(),也许,这将反过来决定哪些任务需要更新。