应用领域驱动设计规则“仅通过聚合根访问聚合”时如何画线

Posted

技术标签:

【中文标题】应用领域驱动设计规则“仅通过聚合根访问聚合”时如何画线【英文标题】:How do I draw the line when applying the Domain Driven Design rule "only access aggregates via the aggregate root" 【发布时间】:2016-02-17 19:54:08 【问题描述】:

我们有一个 SaaS 应用程序。

数据库中有公司、用户和实体的行(一般用于用户处理的东西)

所以公司 A 控制用户 A-F

用户 A-C 有权查看实体 A 用户 D-F 有权查看实体 B

当我为实体 A 及其聚合实体创建有界上下文时,是否只能通过公司 A 访问实体 A?

我正在尝试找出在哪里应用“仅通过聚合根访问聚合”规则。

我在哪里画线?

什么时候A公司和B公司都可以访问实体A?

【问题讨论】:

规则是只通过聚合根访问实体。还有另一条规则规定聚合根应仅由身份引用。在不了解您的域的情况下,我倾向于认为 Company、User 和 Entity 都是聚合根,但话又说回来,它取决于需要强制执行的不变量... 【参考方案1】:

关于聚合的想法是它们代表一致性边界。这意味着应该可以同时加载两个不同的聚合,修改两者,然后将它们保存回数据库。一旦您将同一实体作为多个聚合的一部分,就不再保证这一点。如果您这样做,推理您的域中的一致性和并发性将变得很多变得更加困难。

这就是为什么一个实体必须只属于一个聚合。

解决方案通常很简单:使实体成为自己的聚合体。这意味着您只能通过 ID 从之前被关联引用的聚合中引用它。请注意,这也解决了您“仅通过聚合根访问聚合”的问题。

【讨论】:

不同意。如果您确定实体 AB 一直在更改,则没有理由将它们放在单独的聚合中。即使 A 的两个 instances 可以引用 B 的相同 instance 也不是一个正当的理由 - 并发方面,拆分聚合不会改变在给定时间段内竞争修改AB 的客户端数量。【参考方案2】:

“仅通过聚合根访问聚合” 不是聚合设计的有用规则。在编程时要记住聚合概念的实际副产品——如果你可以不受限制地直接访问任何实体,聚合基本上是无用的。

在建模时,您应该寻找倾向于在同一业务事务中一起更改和/或必须保持一致的实体,并围绕这些实体绘制聚合边界。

很有可能Company 中的任何数据都不需要始终与其Entities 保持一致,并且它们不会一起更改,因此通过“保持聚合小”建议,您可能应该将它们设为 2 个聚合。但只有您知道您的域中的不变量并且可以分辨。

【讨论】:

以上是关于应用领域驱动设计规则“仅通过聚合根访问聚合”时如何画线的主要内容,如果未能解决你的问题,请参考以下文章

浅谈如何理解领域驱动设计

解构领域驱动设计:领域驱动设计的核心之分层架构

领域驱动设计:服务和聚合中的领域规则

实现DDD领域驱动设计: Part 2

重新解读DDD领域驱动设计

DDD领域驱动设计 - 设计文档模板