Question

I am developing a CMS type application and am looking to use some ddd tactical patterns. Here is the situation:

The application deals with the authoring and publishing of items.

Items are grouped together in a workflow group. Within that group, one item may be marked as 'Published', one item as 'Working' and any number as 'Archived'.

A item can only be edited when it is in the 'Working' state.

When a working item is published it replaces its corresponding published item (if there is one), which would be then marked as Archived.

If no draft exists, a new working version may be created by copying the published version or any of the archived versions.

The question is, following the guidance that Aggregates should encapsulate system invariants, should Workflow Group be an Aggregate root - encompassing all its items?

My worry is that this would make quite a large aggregate, and it would stop items being globally accessible (i.e. all interaction would have to go through the Workflow Group AR).

The alternative I see is to make Item an Aggregate Root, and then have a Domain Service deal with the transactions and invariants. For instance:

PublishWorkingItem(int itemId) 
{
    Item workingItem = itemRepo.GetWorkingItem(itemId);
    Guid groupId = workingItem.GroupId;
    Item publishedItem = itemRepo.GetPublishedItemForGroup(groupId);
    if(publishedItem != null) 
    {
        publisheditem.Archive();
    }
    workingItem.Publish();  
}
Was it helpful?

Solution

An AR should have its own life cycle. This is something that you should be able to pick up from your domain expert.

An AR is also about having sharp edges around highly cohesive object graphs.

If you find that you have an AR inside another you need to remove the contained AR and replace it with either only the contained ID or a Value Object.

In your case there may be a difference between, e.g., an active item and an archived item so that archived items are not part of the Workflow AR. But you may end up making Item an AR in which case your Workflow AR could contain a list of active item IDs / VOs.

Just some thoughts :)

OTHER TIPS

If you haven't already, I strongly recommend reading vaughn vernon's series of articles about effective aggregate design. Part II suggests that you should consult with your domain expert on whether it may be accepted to have stale data in the system. If the answer is yes, you may consider having small aggregates (e.g. Item in your domain) that maintain eventual consistency rather than transactional. For example, this may mean that for some small amount of time, there may be two items with the published state, but eventually only one item will be published. You can achieve this kind of behavior using domain events. Having a large transactionally consisted aggregate is also an option, but it may result in high concurrency contention if many users attempt to manipulate the same group concurrently.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top