Can there be multiple aggregates for the same concept

aggregatedomain-driven-design

Say I have the concept of a User; a very basic structure in reality. If the business requires that an aspect of the software needs to display all related 'Posts' for example, how should that be modelled?

  1. Should there be posts as an attribute on the User entity, meaning that every time a User is required simply to verify a login for example, all it's posts must be loaded?
  2. A separate aggregate entirely should be used. What should this aggregate be called? UserWithPosts? What if there are more attributes for related data?
  3. The aggregate root should be an interface User, with a simple Entity called LoginUser, and decorators for extra functionality, like UserWithPosts, UserWithComments etc?

I can't figure out which would be the better approach to avoid scenario 1.

Best Answer

There seems to be a confusion between domain driven design concepts, API design and implementation approach.

Domain design concepts

First a few definitions of Evan's DDD reference book:

  • Aggregate: A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the aggregate, designated as the root.

  • Entity: An object fundamentally defined not by its attributes, but by a thread of continuity and identity.

And keep in mind that this is about the domain. We don't care here how the relationships between the objects will be implemented. Therefore, from what you say:

  • User and related Posts belong to the same aggregate, and User is the root entity thereof. This says that whenever I want to refer to a Post, however it is implemented, I have to access it via the User.
  • it's not clear if Post within the aggregate is an entity or a value object. The difference is about identity semantics: is a post that is updated (e.g. correction of a typo) still the same post or would if be considered as another post ? Personally I'd opt for the entity, but up to you to see what fits best your domain.

API design & implementation model

The domain model is independent of any specific implementation. But in order to implement it, you'll have to define:

  • An API, that defines how the domain is exposed to the application layers that use the model (e.g. controllers and views).
  • An implementation approach for managing the implementation dependent internals of the model, for example to ensure the persistence (e.g. use of an Object-Relational mapping or use of a NOSQL database).

The domain model shall not be a prison that imposes you to blindly do things that hamper performance, but a guide to structure better your software.

In your specific case, you could for example use lazy loading: your API may give the impression that everything is loaded at once with the User, but in reality, the posts will not be loaded until someone tries to access it via the User (thanks to encapsulation).

But you could also define an API that seems to give direct access to the entities in the aggregate, but which enforce the access to Post to go via User, so that you have the opportunity to safeguard the consistency of the related objects.

You could also, as you suggest yourself, create different kind of User objects in your application to determine what is to be loaded and what could be changed. But then it's an implementation model and no longer the conceptual domain model anymore.