1

I read a lot about DDD but few thing are still unclear. At this moment I have two dilemma

  1. The size of aggregates. How small could be an aggregate? For example we have:
class Car {
    String colorId
    (or String colorCode)
    ...other fields
}   
class Color {
    String code
}

I think in this case Color should be an aggregate with just one field and no business logic. The only choice is how to store information about color in aggregate - keep an Id of Color or keep value. Am I right?

  1. Relations between entities inside of different aggregates. Everywhere I read that it shouldn't happen. Is it mean that I shouldn't keep any kind of relation? What should I do in situations like that:
class Order {
    List<OrderLine>
}
class OrderLine {
}

class Invoice {
    List<InvoiceLine>
}
class InvoiceLine {
}

Probably we should have two aggregates: Order and Invoice but there could be N invoices to one order therefore we need to know which InvoiceLine coresponds with which OrderLine. It could be even more complicated if we allow to issue also one Invoice to many Orders.

In this situation I could:

  • make 4 aggregates - but what with invariants? I won't be able to keep consistency i one document.
  • make 1 aggregate - but if we have also another kinds of documents it will be a huge aggregate, "half a database" in one query
  • 2 AG and keep Id of other line entity (it for sure breaks the rules of DDD)
  • 2 AG but keep relation to lines by line number - each OrderLine/InvoiceLine has its own line number starting with 1 - I could refere to them through AG which have an unique Id and with line number which is unique in a scope of AG (is it break the rules of DDD?)

What is a proper way to solve this kind of problem?

1

First and foremost, the main idea of having a domain model is to wrap your business logic. Second, an aggregate is a set of business-related entities (order and orderline can form an aggregate), each aggregate should have a root, which is logically the one entity that forms transactional consistency boundary, so for example if you delete it you'd delete all related items in the aggregate (if you delete the order would you keep its related order line?)

Now back to your questions:

  1. An aggregate can consist of one entity, this is not only fine, but it is rather recommended to have as simple aggregates as possible (but not simpler). What makes an aggregate bigger is actually your business logic (your order-orderline is a good example).
  1. You can directly-reference entities inside the same aggregate, otherwise you shouldn't reference anything other than an aggregate root (for example, you can reference an order inside an invoice), and the best practice is to reference other aggregates by identity (usually by defining the Id as a value-object)

For further explanation and detailed examples I recommend Vaughn Vernon's DDD Distilled

0

How small could be an aggregate?

An AGGREGATE can be as small as one domain ENTITY.

Entities, values, and "domain services" are the patterns that normally appear when we are modeling the domain. Properties like Color are normally implemented using Values - the fact that you are thinking that color has "no business logic" is a Big Hint[tm] that you are describing a value.

Entities are the parts of our domain model that manage change over time. If you are, for instance, managing relationships between a VIN and other interesting properties, then you likely have an Entity.

Aggregates are not a domain modeling pattern, but rather a life cycle management pattern (in the original book, aggregates are described in the same chapter as repositories and factories, not in the chapter with entities and values). They are, effectively, a mechanism to ensure that isolated graphs of entities change together in a consistent way.


Relations between entities inside of different aggregates...

Are usually managed by copying identifiers. Suppose that Order 12345 has some relationship to Account 67890, but Order and Account are in different aggregates.

What that will usually look like is an identifier in one aggregate that can be used as a parameter to find the other. Order.Account, for instance, might be a value in Order that holds a copy of an identifier of the Account entity that lives in the other aggregate.

2 AG but keep relation to lines by line number - each OrderLine/InvoiceLine has its own line number starting with 1 - I could refer to them through AG which have an unique Id and with line number which is unique in a scope of AG

Yup, that's pretty common - unless you have a strong reason to believe that you are dealing with an exotic case, I'd recommend starting from this approach and exploring to discover if it introduces additional obstacles.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.