What Belongs to the Aggregate Root

jlembke picture jlembke · May 7, 2009 · Viewed 7.4k times · Source

This is a practical Domain Driven Design question:

Conceptually, I think I get Aggregate roots until I go to define one.

I have an Employee entity, which has surfaced as an Aggregate root. In the Business, some employees can have work-related Violations logged against them:

Employee-----*Violations

Since not all Employees are subject to this, I would think that Violations would not be a part of the Employee Aggregate, correct?

So when I want to work with Employees and their related violations, is this two separate Repository interactions by some Service?

Lastly, when I add a Violation, is that method on the Employee Entity? Thanks for the help!

Answer

jlembke picture jlembke · May 8, 2009

After doing even MORE research, I think I have the answer to my question.

Paul Stovell had this slightly edited response to a similar question on the DDD messageboard. Substitute "Customer" for "Employee", and "Order" for "Violation" and you get the idea.

Just because Customer references Order doesn't necessarily mean Order falls within the Customer aggregate root. The customer's addresses might, but the orders can be independent (for example, you might have a service that processes all new orders no matter who the customer is. Having to go Customer->Orders makes no sense in this scenario).

From a domain point of view, you can even question the validity of those references (Customer has reference to a list of Orders). How often will you actually need all orders for a customer? In some systems it makes sense, but in others, one customer might make many orders. Chances are you want orders for a customer between a date range, or orders for a customer that aren't processed yet, or orders which have not been paid, and so on. The scenario in which you'll need all of them might be relatively uncommon. However, it's much more likely that when dealing with an Order, you will want the customer information. So in code, Order.Customer.Name is useful, but Customer.Orders[0].LineItem.SKU - probably not so useful. Of course, that totally depends on your business domain.

In other words, Updating Customer has nothing to do with updating Orders. And orders, or violations in my case, could conceivable be dealt with independently of Customers/Employees.

If Violations had detail lines, then Violation and Violation line would then be a part of the same aggregate because changing a violation line would likely affect a Violation.

EDIT** The wrinkle here in my Domain is that Violations have no behavior. They are basically records of an event that happened. Not sure yet about the implications that has.