An aggregate is particular kind of entity so first of all we need to know whether the model is an entity or a value object. Once we know it's an entity let's figure out whether it is an aggregate. A transaction should modify a single aggregate instance so the repositories should work with aggregates when possible - retrieve and save aggregates. The aggregate is an entity that may contain other entities and value objects. Some heuristics to discover which objects should be clustered into aggregates:
------ Aggregate A:
------ - Entity B
------ - Value D
------ - Value E
------ - Value F
- Model true invariants - an invariant is a business rule that must be consistent (transactionally or eventually) : If there is a rule saying that Value F = Value D + Value E, we must ensure that D, E and F are persisted together to always preserve that rule.
"Aggregate is one that can be modified in any way required by the business with its invariants completely consistent within a single transaction".
- If we need transactional consistency in A, then although B is an entity, it doesn't make much sense to use B out of A's context, I mean, there is no reason for an entity of kind B to be modified or loaded without aggregate A - Imagine that A is an Invoice and B is an Invoice Line.
- Try to design small aggregates despite of the desire for compositional convenience.
- "Just because you are given a use case that calls for maintaining consistency in a single transaction doesn't mean you should do that. Often, in such cases, the business goal can be achieved with eventual consistency between Aggregates."
The truth is that is really hard to model things up-front. Our current approach is to model the minimum we need for an action to be performed and then evolve. However the fact that we tried to identify aggregates in front of the whiteboard led us to a nice Context Map drawing session that provided us with a better understanding of the domain.
Source: Implementing Domain Driven Design - Vaughan Vernon