Simple Code
Simple Code

Reputation: 2574

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

Depending on the example that vaughn vernon gave in his book about Agile.He designed Product as an Aggregate and BackLogItem as an aggregate which references Product AR by Id.

Now we need to plan new BackLogItem inside BackLogApplicationService as following:

 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
        }
        //...
    }

And the factory method will be like :

   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;
    }

Did I violate the consistency boundary of the BackLogItem Aggregate inside the Factory method because I am using some information about Product state to decide planning new backLogItem into that Product, if so how I can prevent planning new backLogItems into that product in case that product is suspended or inactive?

Upvotes: 2

Views: 577

Answers (1)

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57194

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

The core guideline is this: any given transaction modifies at most one aggregate in your model.

So if your model includes a relationship between a Product and a BacklogItem, then you can modify a Product using a stale copy of data from a BacklogItem, or you can modify a BackLogItem using a stale copy of data from a Product.

To help make this clear in code, we use interfaces to pass messages from one aggregate to another. In a use case where we are going to modify a Product, we have a product interface that supports mutations, and a back log item interface that only supports queries. If we are going to update the back log item, then the item has the mutable interface and the product interface is read only.

In other words, we use appropriate role interfaces to ensure that no code author inadvertently violates the rule of modifying more than one aggregate in a transaction.

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

Right - when Evans described DDD in 2003, he was working in a coding style that didn't rely upon interfaces; to have an instance of a product meant to have all of the capabilities of the product available at once.

Role interfaces help to reduce the number of errors made possible by this flexibility. Simply not making mistakes is also an option.

Upvotes: 2

Related Questions