【问题标题】:How to implement references beetwen aggregates in ddd?如何在 ddd 中实现引用 beetwen 聚合?
【发布时间】:2015-05-28 14:19:42
【问题描述】:

在 ddd 中,实体可以引用同一聚合的实体,或另一个聚合根(但不能引用另一个聚合内的实体)。

  1. 如何实现这样的引用?
  2. 实体的方法如何访问被引用的聚合根?
  3. 允许实体与其他聚合根的方法是什么?

对于 1. 和 2. 我的问题是,实体不应该有权访问存储库。此外,魔术延迟加载机制并不总是可用的,我认为出于同样的原因应该避免使用。因此,当存储库加载聚合时,存储库是否应该解析其中每个实体的所有引用(并且加载所有引用的其他聚合)?或者“引用”只是一个 id 和实体外部的某个人(命令处理程序或从存储库加载聚合并调用方法的任何人)也使用此 id 加载另一个聚合,然后将其作为参数作为参数提供给方法在下面的例子中?

agg1 = repo1.Load(id);
agg2 = repo2.Load(agg1.refId);
agg1.mymethod(agg2);

对于 3。我认为应该在另一个聚合上调用的唯一方法是不改变另一个聚合的查询方法(在 cqs 意义上),因为每个事务只应该更改一个聚合。对吧?

【问题讨论】:

  • 好吧,如果第一个聚合需要第二个聚合来完成它的职责,您还可以存储聚合引用并依赖能够重新水化该结构的 ORM。如果您经常发现自己必须加载 agg2,那么这对我来说是有意义的,但我可能是错的。

标签: domain-driven-design ddd-repositories


【解决方案1】:

至于问题 1. 和 2. 你说的很好,而且大部分时间都是这样。您通过 id 引用其他聚合并在应用程序服务中在域逻辑之外检索它们。不应在聚合中加载其他聚合(违反 SRP 除外)的原因是您无法控制正在发生的事情,与延迟加载相同。您可以轻松地编写代码,在可以加载一次的情况下,从 DB 加载相同的聚合数十次。你可以使用缓存,但也会有过时数据等问题。

但是,有时,您需要在“DDD”之上进行“性能驱动设计”,然后将聚合加载到另一个聚合中,但这种情况很少见。

对于您对 3 的回答。在 CQRS 查询中,您甚至不使用存储库或聚合,因为您只想获取数据,不涉及域逻辑。

【讨论】:

    猜你喜欢
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    相关资源
    最近更新 更多