Domain Driven Design – Can Two Aggregates Have the Same Root?

aggregateArchitecturedesigndomain-driven-design

For the purpose of separating different functionality into different classes, I have two following Aggregates:

  1. ActiveEmployee

    • AssignTask ()
    • ReassignManager ()
    • Deactivate (string reason)
  2. InactiveEmployee

    • GetReasonForDeactivation ()
    • Reinstate ()

Both aggregates share the same root, dbo.Employee.

EmployeeID servers as a primary key for both Aggregates.

The repository instantiates the first one, or the second one based on a boolean flag dbo.Employee.IsActive.

Since I follow the rule that only one aggregate can be modified in one transaction, I will never encounter a situation where I load both aggregates with same ID, ending up with InactiveEmployee with ID 3 and ActiveEmployee with ID 3 in same transaction.

Is this good DDD? Does DDD allow for having two aggregates with same root?
Can we differentiate Aggregate types based on a flag?

UPDATE 1:

When I said that both aggregates share the same root, what I meant was that both Aggregates represent a row in dbo.Employee table.

In my understanding, a root of the Aggregate is the entity which is uniquely defined in our domain. It does not mean that that entity has to exist as a real class, it's identity is what matters. Every other Aggregate that wants to reference Inactive/ActiveEmployee will hold a reference to the EmployeeID, not the reference to object instance.

Best Answer

You need to understand that DDD is not about primary keys, rows or tables - these are just means to implement it.

Aggregate root is usually implemented as a class, because you are expected to access all the functionality and data of the aggregate through the root. It therefore needs to have some behavior, something which primary key of the table can't have. Primary benefit of this is the encapsulation of aggregates - its logic is completely contained inside the aggregate and doesn't leak outside which greatly reduces the coupling (and as a consequence complexity) of the application.

It follows that each aggregate has its own aggregate root, so two aggregates can't have the same root (if they have, there is effectively just one aggregate).

In your case, you probably want to have two independent aggregates (ActiveEmployee, InactiveEmployee) which are backed by the same table (which is fine because it's totally out of DDD's scope). But then remember that there's actually no dbo.Employee entity in your domain model, it's just a table on a lower (persistence) layer.