如何在 ddd 中实现引用 beetwen 聚合?
How to implement references beetwen aggregates in ddd?
在 ddd 中,实体可以引用同一聚合或另一个聚合根的实体(但不能引用另一个聚合内的实体)。
- 如何实施这样的参考?
- 实体的方法如何访问引用的聚合根?
- 实体的方法允许对其他聚合根做什么?
对于 1. 和 2. 我的问题是,实体不应该访问存储库。魔术延迟加载机制并不总是可用,我认为出于同样的原因应该避免。那么当存储库加载聚合时,存储库是否应该解析其中每个实体的所有引用(以及加载所有引用的其他聚合)?或者 "reference" 只是一个 id 而实体外部的某个人(命令处理程序或从存储库加载聚合并调用方法的任何人)也使用此 id 加载另一个聚合,然后将其作为参数如下例?
agg1 = repo1.Load(id);
agg2 = repo2.Load(agg1.refId);
agg1.mymethod(agg2);
对于 3。我认为应该在另一个聚合上调用的唯一方法是不改变另一个聚合的查询方法(在 cqs 意义上),因为每个事务只应更改一个聚合。对吗?
关于问题1、2,你说的很好,大部分情况下都是这样的。您通过 id 引用其他聚合并在应用程序服务中的域逻辑之外检索它们。你不应该在聚合中加载其他聚合的原因(SRP 违规除外)是因为你无法控制正在发生的事情,与延迟加载一样。您可以轻松地编写代码,在可以加载一次的情况下从数据库中加载相同的聚合数十次。您可以使用缓存,但也会有陈旧数据等问题
然而,有时,您需要在 "DDD" 上执行 "Performance Driven Design",然后在另一个聚合中加载聚合,但这种情况很少见。
对于问题 3 的回答。在 CQRS 查询中,您甚至不使用存储库,也不使用聚合,因为您只是想获取数据,那里不涉及域逻辑。
在 ddd 中,实体可以引用同一聚合或另一个聚合根的实体(但不能引用另一个聚合内的实体)。
- 如何实施这样的参考?
- 实体的方法如何访问引用的聚合根?
- 实体的方法允许对其他聚合根做什么?
对于 1. 和 2. 我的问题是,实体不应该访问存储库。魔术延迟加载机制并不总是可用,我认为出于同样的原因应该避免。那么当存储库加载聚合时,存储库是否应该解析其中每个实体的所有引用(以及加载所有引用的其他聚合)?或者 "reference" 只是一个 id 而实体外部的某个人(命令处理程序或从存储库加载聚合并调用方法的任何人)也使用此 id 加载另一个聚合,然后将其作为参数如下例?
agg1 = repo1.Load(id);
agg2 = repo2.Load(agg1.refId);
agg1.mymethod(agg2);
对于 3。我认为应该在另一个聚合上调用的唯一方法是不改变另一个聚合的查询方法(在 cqs 意义上),因为每个事务只应更改一个聚合。对吗?
关于问题1、2,你说的很好,大部分情况下都是这样的。您通过 id 引用其他聚合并在应用程序服务中的域逻辑之外检索它们。你不应该在聚合中加载其他聚合的原因(SRP 违规除外)是因为你无法控制正在发生的事情,与延迟加载一样。您可以轻松地编写代码,在可以加载一次的情况下从数据库中加载相同的聚合数十次。您可以使用缓存,但也会有陈旧数据等问题
然而,有时,您需要在 "DDD" 上执行 "Performance Driven Design",然后在另一个聚合中加载聚合,但这种情况很少见。
对于问题 3 的回答。在 CQRS 查询中,您甚至不使用存储库,也不使用聚合,因为您只是想获取数据,那里不涉及域逻辑。