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

时间:2017-10-03 10:06:25

标签: domain-driven-design aggregateroot

取决于vaughn vernon在其关于Agile的书中给出的示例。他将Product设计为Aggregate,将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;
    }

我是否违反了Factory方法中BackLogItem聚合的一致性边界,因为我正在使用有关产品状态的一些信息来决定将新的backLogItem规划到该产品中,如果是这样的话我怎么能阻止在该产品中规划新的backLogItems产品是暂停还是不活动?

1 个答案:

答案 0 :(得分:1)

  

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

核心准则是:任何给定的交易最多可以修改模型中的一个聚合。

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

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

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

  

我们的答案意味着上面的代码它没有违反DDD,因为我不在这里更新产品聚合(因为ddd不允许每次事务更新多个聚合

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

角色接口有助于减少这种灵活性带来的错误数量。只是不犯错误也是一种选择。