views:

76

answers:

1

If Book aggregates Chapter which in turn aggregates Page, then what should be the aggregate root? One possibility might be:

Book is an aggregate root with Chapter as a leaf and Chapter is an aggregate with Page as a leaf.

In this scenario, Chapter is a leaf in one aggregate and a root in another. Is this okay? Would it make sense in this scenario to have two repositories, one for Book and another for Chapter? If so, then couldn't the Chapter repository be used to circumvent the fact that access to Chapter should only happen via Book? What would be the best way to handle a situation like this?

A: 

In my opinion, the whole idea of aggregate roots make sense only when there is a single root for a given aggregate. Which one -- it depends on your requirements. Let's examine two possibilities:

  1. Book is a root and it contains Chapters containing Pages. This design is useful when your usage scenarios all include interacting with books: users select books and apply their operations/commands on whole books. Notice, that the Book aggregate is in 'operations' layer of your domain model -- it, as a whole, represents concepts what part of are day-to-day business.

  2. Chapter is the root. Is contains Pages. It also has reference to Book. This design is useful when usage scenarios focus on interacting with individual chapters. Chapter aggregate is in 'operations' layer now. Book forms an aggregate by itself but is is placed in 'potencial/capabilities' layer beneath the operations layer. This means that books are an asset to the organization, an enabler for the business, but are not part of day-to-day activities. Moreover, books don't know anything about being referenced by Chapters.

To sum up, all depends on specifics of you case, the requirements you have. Be aware that layers in the domain model ore primarily a business concept, not technical one -- they hep you to model the domain well. For further information please read Eric Evans' Domain-Driven Design, especially 'Large scale structure' part.

Szymon Pobiega
Thanks Szymon. These are good points that clarify the reasoning behind the decision. If I may, I'd like to extend the situation slightly: Let's say that Book also contains Author. If you are supporting two use cases, one in which the focus is on Chapters (and their collection of Pages), and another in which the focus is on Books (and their collection of Authors), you now have reason to make Chapter the aggregate root in one scenario and Book the aggregate root in the other scenario. But Book contains Chapter, so we have one aggregate root that contains another aggregate root. Now what?
MylesRip
Some of DDD experts (like Udi Dahan) acknowledge that aggregate roots aren't structural elements of model and can be placed differently based on particular use case. That can be solution to your case. In the Book aggregate both Chapter and Book can be aggregate roots in different use cases. This approach is described here: http://www.udidahan.com/2009/06/29/dont-create-aggregate-roots/. Aggregate root per use case is not one of 'classic' DDD principles, however, and is a subject of many discussions.
Szymon Pobiega
Yes. That makes sense. Thanks for the link to Udi's article. It was quite interesting.
MylesRip