Search code examples
domain-driven-designaggregateaggregateroot

Association between aggregates, how to decide between holding reference to the object or only to its identity


For exemple, giving a performance having multiple performers...

First option:

Performance (1) ---> (*) Performer

Second option:

Performance
+PerformerIds[]

1st option Pros:

  • Easier access for query purpose (lets say I don't want to use CQRS)
  • When we look at the domain model it seems easier to understand, the relation between Performance and Performer is more visible

1st option Cons:

  • A Performance object is heavier to load (could possibly be fixed with lazy loading)
  • More coupling

2nd option pros and cons are obviously the opposite of the first option, harder access to performers from the performance, model diagram harder to understand, lighter to load and less coupling.

I kind of like the first option, because, there is no way a Performance object will ever use the Performer object. That relation is more like a data relation / query model. But it also makes the domain model diagram less clear, in my opinion, so i'm not sure if I should which solution to use.

Could my problem here be that I'm trying to use the same class diagrams for domain experts and for developers ? and/or modeling for query primarily rather than for updating ?


Solution

  • how to decide between holding reference to the object or only to its identity

    Holding a reference to an identity of related Aggregate Roots (ARs) makes their boundaries explicit.

    Sure each AR still holds references to all its Entities but it becomes very explicit in your domain model whether you reference Aggregate Roots or Entities.

    • If you hold references to related Aggregate Roots (ARs) it's very easy to cross boundaries between them.
    • It can be very easy to change few aggregates at the same time, especially if you use ORM or have Unit of Work implemented. So your aggregate roots are not transaction boundaries any more.
    • If you hold only identifiers to related Aggregate Roots (ARs), in order to access a related AR you have to load it from repository first. It's a trade off. It becomes very explicit when you cross a boundary of one aggregate and query another one.

    What I don't like of it is that when you look at a class diagram, all you see is separate aggregates that does not have any association between them, that does not look very useful to show the domain concepts that are related.

    Your domain model is a "model" and it's up to you to make design decisions.

    If all your Aggregate Roots are small, and you use an ORM that does a lot of magic for free (NOTE: There is always a price), and a value of seeing references on a class diagramme is bigger than value of seeing boundaries then try with holding a reference to related ARs, even if your code doesn't really need it.

    And then evaluate your model over a time.