DDD 中的聚合根之间允许哪个级别的通信?

Which level of communication is allowed between Aggregates Roots in DDD?

根据 vaughn vernon 在他关于 Agile.He 的书中给出的示例,将 Product 设计为聚合,将 BackLogItem 设计为通过 Id 引用 Product AR 的聚合。

现在我们需要在 BackLogApplicationService 中规划新的 BackLogItem 如下:

 public class ProductBacklogItemService
    {
        //...

        public void planProductBacklogItem(
        String aTenantId, String aProductId,
        String aSummary, String aCategory,
        String aBacklogItemType, String aStoryPoints)
        {
            Product product =
            productRepository.productOfId(
            new TenantId(aTenantId),
            new ProductId(aProductId));

            BacklogItem plannedBacklogItem =
            BacklogItem.planBacklogItem(
            aSummary,
            aCategory,
            BacklogItemType.valueOf(aBacklogItemType),
            StoryPoints.valueOf(aStoryPoints),
            product);

            backlogItemRepository.add(plannedBacklogItem);

           //commit the changes
        }
        //...
    }

工厂方法将是这样的:

   public static BacklogItem planBacklogItem(String aSummary, String aCategory,BacklogItemType aType, StoryPoints aStoryPoints,Product product)
    {
        if(product.Suspended)
          //here prevent planning this backlogitem
        //...
        backLogItem.ProductId=product.Id

        return backLogItem;
    }

我是否违反了工厂方法中 BackLogItem 聚合的一致性边界,因为我正在使用一些关于产品状态的信息来决定将新的 backLogItem 计划到该产品中,如果是这样,我如何才能防止将新的 backLogItem 计划到该产品中产品暂停或停用的情况?

Which level of communication is allowed between Aggregates Roots in DDD?

核心准则是:任何给定事务最多修改模型中的一个聚合。

因此,如果您的模型包含产品和 BacklogItem 之间的关系,那么您可以使用来自 BacklogItem 的陈旧数据副本修改产品,或者您可以使用来自产品的陈旧数据副本修改 BackLogItem .

为了帮助在代码中明确这一点,我们使用接口将消息从一个聚合传递到另一个聚合。在我们要修改产品的用例中,我们有一个支持突变的产品接口,以及一个仅支持查询的后台日志项接口。如果我们要更新后台日志项,则该项具有可变接口,而产品接口是只读的。

换句话说,我们使用适当的role interfaces来确保没有代码作者无意中违反在事务中修改多个聚合的规则。

our answer it means the above code it does not violate DDD because I don't here update the product aggregate(because of ddd it's not allowed to update more than one aggregate per transaction

对 - 在 Evans described DDD in 2003 时,他使用的是一种不依赖于接口的编码风格;拥有一个产品实例意味着可以立即使用该产品的所有功能。

角色接口有助于减少这种灵活性可能导致的错误数量。干脆不犯错也是一种选择。