Search code examples
domain-driven-designaggregateroot

DDD: should "Comment" in an "Article" be an aggregate root?


I am starting to design a first simple application DDD-style, and I am starting to see how the concepts work together.

If I design a classic blog application, Article class will be one of my aggregate roots. I want to retrieve articles, manage and delete all the related data (publication date, authors...). I am having difficulties with comments. At first, Comment seems to be an entity that is part of the Article aggregate: a comment is created in relation to an article, if I delete an Article, I will delete related comments.

Then I want to display a small box on the blog with the latest comments posted on the blog, for any article. So it looks like I want to retrieve comments from my data store (and only comments). From my understanding of DDD ideas, that makes it an aggregate root. But that does not seem totally right as Comment seems to depend strongly on Article.

How would you model it?

Thanks.


Solution

  • When you think about it you will probably find various reasons why a Comment should be an Aggregate itself:

    • You want to list the latest comments
    • You may want to list all comments by a particular user
    • You may want comments to be nested (a comment being a reply to another comment)
    • You may want to approve/reject comments through an admin interface
    • A user may want to edit or delete his/her comment
    • ...

    I take the following as a general rule of thumb: Keep your Aggregates as small as possible. When in doubt, err on the side of more Aggregates.

    By modelling it this way, you can attach the comments to multiple objects, like Article and User

    Comment
        string Text
        string UserName
        bool IsApproved
    
    Article
        string Title
        string Body
        ...
        List<CommentIds> CommentIds
    
    User
        string UserName
        ...
        List<CommentIds> CommentIds
    
    ListOfTenLatestComments
        List<CommentIds> CommentIds