DDD and Aggregates

I started reading Eric Evans’ book Domain Driven Design.  (Seemed like one of those foundation books you have to have read if you want to be a certain type of developer)  I decided to give it a go after I got about halfway through the “Domain Driven Design Quickly” pdf – it seemed interesting enough that I wanted to have a go at the real thing.

Anyway, one thing it talks about is Aggregates… basically, a tree of dependent objects that don’t mean anything alone-like line items to an order, as opposed to a customer that is an entity that has meaning by itself.  I guess I haven’t explored things enough yet, but I’m thinking abouton something I’m looking at-I’ve got something like an order, and something like a line item.  There should be no separate repository for the line item.  However, in practice you may need to deal with the line item by itself, for instance the “edit the line item” screen on a website.  In a desktop app, you’d pull out the line item w/ roder, keep that around, and then save when the editing’s done.  However with this web scenatio, you come back from the editing screen and have… some IDs.  Sure, you may have selected the line item from the order… but as the web is stateless, you don’t have your order and order item all ready to update, you’ve got to rebuild that and apply the changes before a saving.  So, you’d pull out that line item from the repository *via the ID*. Or if you prefer, pull out the order via its ID, then iterate through its line items and pick out the relevant line item from the line item collection by ID.. also messy-you preserve the aggregate idea since there’s now no repository for  line items, but you’ve got iteration, and worse, a domain-level usage of picking by ID, which feels like bleed-through.  But you really need the order and the order item, so you can make your changes and then save.  Uh, I guess you can put them in your session, but that just seems even worse than either of the above options due to unreliability.  But maybe that’s me being pessemistic.  anyway, is there a clean way do deal with this?  Or at least a generally agreed-upon lesser evil?

Tags:

6 Responses to “DDD and Aggregates”

  1. MotoWilliams says:

    Did you ever come to a solution on this topic? I’m in the same situation at the moment.

  2. ajepst says:

    Take this all with a grain of salt, since I haven’t gotten to finishing the book and am not sure what Evans says on the matter, but I’ve considered this a bit since I originally wrote this post. Upon looking at this post later, I think that if it’s valid to edit a line item truly by itself, maybe that line item is an aggregate. If not, it really should probably be done through the order. I don’t think you can get away from the LineItemID usage at least a bit (as that’s all you have at the web level), but I think working with it through the Order is the lesser evil. You can pass both the OrderID and LineItemID in the URL-this could be very nice with a REST format (maybe /orders/15/lines/3/ ) Then you might have a method on Order that takes a line ID and iterates for the matching child in the collection of lines. It’s a little weird to work with the ID at all, but I think it’s the best compromise. In this case, LineItem really IS a child of Order-you’ll always go through the Order page first to go to the LineItem page, so you’ll already have the ID, just stick it in the URL. And if do you find yourself working with LineItems when you don’t have the Order handy, maybe LineItem is an aggregate root.

  3. Jake says:

    Why do you need to “edit the line item” through an Order? LineItem should be an value object which means you do not need to change it. LineItem is a part of an Order so when you “edit the line item”, you don’t edit the item itself you edit the Order.
    If you meant “edit the line item” as an admin, who needs to have line item info up-to-date, it’s an Entity not a value object. but this time we’re talking about different context. Entity and Value objects are determined in the context.

  4. ajepst says:

    Jake, I’m certainly not an expert on DDD, it’s something I’m feeling my way through, and I’m probably misinterpreting things here and there. I agree that the wording of saying you edit the order, not the line item is probably better. Interesting point about Entity and Value objects being determined in the context-I’ll have to think about that.

  5. Greg Young says:

    “However, in practice you may need to deal with the line item by itself, for instance the “edit the line item” screen on a website.”

    I think this is the crux of the issue. Do you actually know this? Aggregates are built up around invariants and where consistency boundaries lie. Very often editing a line item requires the entire order in order to validate whether the update to the line item is acceptable (consider a maximum total amount for an order or that you can only order x count of items that are on sale within the same order)

    HTH

    Greg

  6. Everything depends on the specifics of a project, but…the following sounds reasonable to me.

    Line Item should be a Value Object, it should have no identity outside of the Order that it belongs to, therefore it should not have it’s own repository. It should be impossible to simply load edit and save changes to a line item without the Order knowing about it.

    In fact being a value object Line Items should be immutable. What you really want to do is replace an existing line item with a different line item. That “replace” is an operation that should happen at the Order level.

Leave a Reply

This blog is kept spam free by WP-SpamFree.