29

我目前正在大量使用 DDD,并且在从其他聚合根加载/操作聚合根时遇到问题。

对于模型中的每个聚合根,我也有一个存储库。存储库负责处理根的持久性操作。

假设我有两个聚合根,有一些成员(实体和值对象)。

AggregateRoot1 和 AggregateRoot2。

AggregateRoot1 有一个引用 AggregateRoot2 的实体成员。

  1. 当我加载 AggregateRoot1 时,我是否也应该加载 AggregateRoot2?
  2. AggregateRoot2 的存储库应该对此负责吗?
  3. 如果是这样,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)
    }
}

这只是一个简单的例子,不包括得墨忒耳法则或其他最佳原则/实践:-)

进一步的评论表示赞赏。

4

3 回答 3

62

我自己也遇到过这种情况,得出的结论是,让子聚合以优雅的方式工作太让人头疼了。相反,我会考虑您是否真的需要将第二个聚合引用为第一个聚合的子级。如果您只保留聚合 ID 的引用而不是实际聚合本身,这会使生活变得更加轻松。然后,如果存在涉及两个聚合的域逻辑,则可以将其提取到域服务中,如下所示:

public class DomainService
{
    private readonly IAggregate1Repository _aggregate1Repository;
    private readonly IAggregate2Repository _aggregate2Repository;

    public void DoSomething(Guid aggregateID)
    {
        Aggregate1 agg1 = _aggregate1Repository.Get(aggregateID);
        Aggregate2 agg2 = _aggregate2Repository.Get(agg1.Aggregate2ID);

        agg1.DoSomething(agg2);
    }
}

编辑:

真的推荐这些关于这个主题的文章:https ://vaughnvernon.co/?p=838

于 2011-02-07T13:57:52.627 回答
0

这种方法存在一些问题。首先,您应该为每个聚合拥有一个存储库并完成它。拥有一个调用另一个存储库的存储库是对这一规则的突破。其次,关于聚合关系的一个好的做法是一个根聚合应该通过它的 id 与另一个根聚合通信,而不是有它的引用。这样做,您保持每个聚合独立于另一个聚合。仅在根聚合中保留组成相同聚合的类的引用。

于 2020-11-30T12:51:31.393 回答
-4

也许 AggregateRoot1 存储库在构建 AggregateRoot1 实体时可以调用 AggregateRoot2 存储库。

我认为这不会使 ddd 无效,因为存储库仍负责获取/创建自己的实体。

于 2011-02-07T09:40:51.863 回答