Domain Driven Design – Should Root Aggregate Hold Reference to Another Root Aggregate?

domain-driven-designobject-oriented

When following Domain-driven design (DDD), is it correct for a root aggregate to hold a reference to an internal entity that happens to be the root entity on a separate aggregate?

I believe this is not correct, mainly because of this rule on the blue book:

Nothing outside the AGGREGATE boundary can hold a reference to
anything inside, except to the root ENTITY. The root ENTITY can hand
references to the internal ENTITIES to other objects, but those
objects can use them only transiently, and they may not hold on to the
reference. The root may hand a copy of a VALUE OBJECT to another
object, and it doesn't matter what happens to it, because it's just a
VALUE and no longer will have any association with the AGGREGATE.

If a root aggregate holds a reference to another root aggregate the boundary of the former is violated and the whole concept of an aggregate is corrupted, so I believe if a root aggregate looks like needing to hold a reference to another root aggregate, then I need to create a different entity, that will probably share some of the same members as the other root entity, but will not have a global identity, as this other rule in the book states:

Root ENTITIES have global identity. ENTITIES inside the boundary have
local identity, unique only within the AGGREGATE.

I believe this would be the correct way to go, but since it feels repetitive and redundant (when taken off the context of DDD, with pure OOP) I am asking for some feedback.

Best Answer

You might be overinterpreting the book. It basically says : anything outside an Aggregate cannot hold a reference to anything inside it except the root. Therefore, holding a reference to a root is legit. Holding a reference to a root doesn't mean it's part of your own aggregate and that you can control its invariants. It keeps its own invariants and autonomy.

However,

  • A commonly accepted good practice is to refer to an AR by storing its ID, not a full reference.
  • More modern approaches to aggregate design (see the Red Book) advocate a cleaner separation between Aggregates. A business transaction should only change the state of a single Aggregate. Under this assumption, the need to store a reference to another Aggregate tends to disappear because you're not going to modify 2 aggregates at the same time.

is it correct for a root aggregate to hold a reference to an internal entity that happens to be the root entity on a separate aggregate?

This never happens. A Value Object can be part of multiple Aggregates, but not an Entity. The reason is, nothing would then prevent you from sharing the same entity instance between Aggregates. Let's say that entity instance E belongs to both aggregate instances A and B. Since the premise of DDD is that the Aggregate is the entry point, you would be able to load A, modify entity E through it, all the while silently violating invariants from B (that you didn't load).

See the answer from Greg Young here : http://domain-driven-design.3010926.n2.nabble.com/Can-an-Entity-be-Shared-across-many-Aggregates-td7579277.html