【发布时间】:2011-02-07 09:28:04
【问题描述】:
我目前正在大量使用 DDD,但在从其他聚合根加载/操作聚合根时遇到问题。
对于我模型中的每个聚合根,我也有一个存储库。存储库负责处理根的持久性操作。
假设我有两个聚合根,有一些成员(实体和值对象)。
AggregateRoot1 和 AggregateRoot2。
AggregateRoot1 有一个引用 AggregateRoot2 的实体成员。
- 当我加载 AggregateRoot1 时,我是否也应该加载 AggregateRoot2?
- AggregateRoot2 的存储库应该对此负责吗?
- 如果是这样,AggregateRoot1 中的实体是否可以调用 AggregateRoot2 的存储库进行加载?
另外,当我在 AggregateRoot1 中的实体与 AggregateRoot2 之间创建关联时,应该通过实体还是通过 AggregateRoot2 的存储库来完成?
希望我的问题有意义。
[编辑]
当前解决方案
在Twith2Sugars 的帮助下,我想出了以下解决方案:
如问题中所述,聚合根可以具有引用其他根的子级。将 root2 分配给 root1 的其中一个成员时,root1 的存储库将负责检测此更改,并将其委托给 root2 的存储库。
public void SomeMethod()
{
AggregateRoot1 root1 = AggregateRoot1Repository.GetById("someIdentification");
root1.EntityMember1.AggregateRoot2 = new AggregateRoot2();
AggregateRoot1Repository.Update(root1);
}
public class AggregateRoot1Repository
{
public static void Update(AggregateRoot1 root1)
{
//Implement some mechanism to detect changes to referenced roots
AggregateRoot2Repository.HandleReference(root1.EntityMember1, root1.EntityMember1.AggregateRoot2)
}
}
这只是一个简单的例子,不包括得墨忒耳法则或其他最佳原则/实践:-)
感谢更多cmets。
【问题讨论】:
-
就我个人而言,我可以看到这种当前的方法变得混乱,我认为 DavidMasters84 的解决方案更像是一个优雅的解决方案。即将引用保持为 id 并将这种类型的域逻辑提取到域服务。
-
凌乱是这种方法的一个很好的形容词。我可以这么说,因为我最初尝试以相同的方式实现这个问题,而我发现自己陷入了混乱:) 你可能还想在这里阅读关于类似问题的建议:stackoverflow.com/questions/2118088/…
-
我听到了,但是那里没有管理聚合根的存储库,并且出于某种善意,根之间的关系。以及域服务来处理不适合单个实体的行为?在我看来,在阅读域服务的定义时,让域服务负责处理根之间的引用是错误的地方......我可能是错的,所以更支持的论点将不胜感激,谢谢。
-
我对域服务的建议不是用来管理聚合之间的引用;它可以调用涉及多个聚合的功能,即“自然不适合单个实体的行为”。在大多数模型中,所有聚合都以某种形式在关系数据库中相互关联,聚合的目的是将这个依赖图分解为可管理的组。如果您维护模型中所有聚合之间的关系,它将违背聚合的意义。
-
是的,这就是我的想法;你的问题是关于聚合根之间的运行操作,我认为这是域服务适合的地方。我想你很快就会问自己兔子洞有多深......
标签: domain-driven-design repository aggregate loading aggregateroot