Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD - Aggregate Root - Example Order and OrderLine

I am trying to get my hands dirty learning DDD (by developing a sample eCommerce site with entities like Order, OrderLines, Product, Categories etc). From what I could perceive about Aggregate Root concept I thought Order class should be an aggregate root for OrderLine.

Things went fine so far, however I am confused when it define a create order flow from UI. When I want to add an order line to my order object, how should I get/create an instance of an OrderLine object:

  1. Should I hardcode the new OrderLine() statement in my UI/Service class
  2. Should I define a method with parameters like productID, quantity etc in Order class?

Also, what if I want to remove the hardcoded instantiations from the UI or the Order class using a DI. What would be the best approach for this?

like image 497
Chandu Avatar asked Dec 01 '10 21:12

Chandu


People also ask

How do you choose the aggregate root?

When choosing an aggregate root you choose between Transactional Consistency and Eventual Consistency. When your business rules allow you would rather favour Eventual Consistency.

What is aggregate and aggregate root in DDD?

An aggregate is a collection of one or more related entities (and possibly value objects). Each aggregate has a single root entity, referred to as the aggregate root. The aggregate root is responsible for controlling access to all of the members of its aggregate.

Can an aggregate root reference another aggregate root?

[Evans] states that one Aggregate may hold references to the Root of other Aggregates. However, we must keep in mind that this does not place the referenced Aggregate inside the consistency boundary of the one referencing it. The reference does not cause the formation of just one whole Aggregate.

How is aggregate DDD defined?

Aggregate is a pattern in Domain-Driven Design. A DDD aggregate is a cluster of domain objects that can be treated as a single unit. An example may be an order and its line-items, these will be separate objects, but it's useful to treat the order (together with its line items) as a single aggregate.


1 Answers

From what I could perceive about Aggregate Root concept I thought Order class should be an aggreagrte root for OrderLine.

Yes, OrderLine's should most likely be under an Order root, since OrderLine's likely make no sense outside of a parent Order.

Should I hardcode the new OrderLine() statement in my UI/Service class

Probably not, though this is how it happens often and it is made to work. The problem, as I see it, is that object construction often happens in different contexts, and the validation constraints differ depending on that context.

Should I define a method with parameters like productID,quantity etc in Order class?

As in:

public OrderLine AddOrderLine(Product product, int Quantity ... )

This is one way to do it. Notice I used a Product class instead of a ProductId. Sometimes one is preferable to the other. I find I use both a lot for various reasons - sometimes I have the ID and there's no good reason to pull the aggregate root, sometimes I need the other root to validate the operation.

Another way I do this is to implement a custom collection for the children.

So I have:

order.OrderLines.Add(product, quantity);

This feels a little more natural or OO, and in particular if an entity root has many child collections it avoids clutter.

order.AddOrderLine(), order.AddXXX(), order.AddYYY(), order.AddZZZ()

versus

order.OrderLines.Add(), order.ZZZs.Add(), order.YYYs.Add()

Also, what if I want to remove the hardcoded instantiations from the UI or the Order class using a DI. What would be the best approach for this?

This would be a textbook case for the Factory pattern. I inject such a Factory into my custom collections to support instantiation in those Add() methods.

like image 135
quentin-starin Avatar answered Sep 20 '22 15:09

quentin-starin