0

I am almost new to DDD, i have read books and watch pluralsight video from Steve Smith and Julie Lerman. I am quite confident that i understood the concepts except couple of things that stucked in my mind.

First of all i am confused with how should i think about Entity concept. I understand that Aggregate Root is a single unit it includes all the business rules. And it should go to database as single unit. Also i am okay with Aggregate Root can have a collection of some entities. Like a classical example Order --> LineItems. Order is Aggregate Root LineItems are Entity .LineItem is defined by a unique identifier and it has its own business rules. So far so good.

So here are the things that i understand

Aggregate Root --> Single unit

Entity --> Mutable belongs to aggregate root and identified by id

Value Object --> Immutable belongs to entity or aggregate root and identified by properties

What i want to ask over here is, in DDD, is there any example that Aggregate Root can contain one to one relationship with an entity. I have checked couple of examples all i find is collections.

Correct me if I am wrong but I think this is impossible from the definitions since entity can not be exposed to outside of aggregate root. Since it can not be exposed, unique id for one to one relationship doesn't make sense inside the aggregate root. It seems like all of one to one relations with aggregate root of entities becomes value object or another aggregate root depending on the bounded context and what you are interested to do inside the context.

Is this right way of thinking or do i miss some parts?

Let's assume that I have a Customer object belongs to my Order aggregate root. According to my bounded context it could be either value object or most likely another aggregate root but never could be an entity?

EDITED

Thank you for the answers. I think i am confused among terms "Aggregate Root", "Aggregate", "Entity" now it is more clear from what i have read thanks to @VoiceOfUnreason and @ssmith.

Here is two different design that i have made for my purpose. This is very small representation of my bounded context but it could give an idea.

Design 1 enter image description here

Design 2 enter image description here

I didn't write down my business rules over here. But to summarize,

This Bounded Context (Campaign Management) is responsible to manage displays,videos and images and schedule them in different dates and times with some rules like aspect ratio, extensions, mime types and so on for the campaign. I didn't show the other aggregates over here to simplify the diagram.

My problem is with Client and Advertiser in this diagram. In this context, I do not have any business rules that is related with Advertiser or Client. Only thing that I would need is gonna be email address of the client to send some reminders. Otherwise Client and Advertiser is just a lookup for the campaign. Campaign is gonna be pushed from an external system to this bounded context with an event bus or http call. So the client doesn't mean much in this context. Or another way of saying, there is no behavior that is connected to those objects or at least from what I see until now :)

So according to this information, I was thinking to create Advertiser and Client as entity at first but since unique id of them is not gonna be useful, then I have come up with the question that I have asked here. And you can see two different designs that i have made one with value object and other with aggregate root. If i would go with aggregate root, then probably I will move Client and Advertiser to another bounded context. And use that context just for lookup. And if things change in the future, this generic context will evolve. That's what I am leaning onto right now, don't know if it is the right way though.

2 Answers2

1

Entity --> Mutable belongs to aggregate root and identified by id

You've gotten yourself a little bit tangled here (not your fault, the lines are unclear).

Entities are a modeling the domain in software pattern (chapter 5 of the "blue book"). Aggregates are a lifecycle management pattern (chapter 6 of the "blue book"). An aggregate root is a role within an aggregate fulfilled by one of the domain model entities within the aggregate root.

So we have an "order aggregate" that includes an order and line items and so on, and the order entity would normally be the root of that aggregate.

is there any example that Aggregate Root can contain one to one relationship with an entity

So here, the answer is yes - there are many cases where an aggregate will have only a single entity within it, and that entity will serve in the role of the aggregate root.


Let's assume that I have a Customer object belongs to my Order aggregate root. According to my bounded context it could be either value object or most likely another aggregate root but never could be an entity?

Normally, we would expect a single customer to have many orders, so it would be a little bit strange to model the customer entity inside of the order aggregate.

But we might have include in the order a copy of the customer's identity (so that we can look up the customer) and possibly a cached copy of the customer's data (copied at some point in the past) -- not necessarily all of the customer's data, but the data that is necessary for the order to perform its business functions.


Is there any example that you might share?

I think you'll find that in this sample domain model that only the root object is modeled as an entity in the Cargo aggregate.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91
  • Thank you for the answer. **So here, the answer is yes - there are many cases where an aggregate will have only a single entity within it, and that entity will serve in the role of the aggregate root. ** Is there any example that you might share? – Can Günaydın Feb 28 '23 at 18:43
  • I was just checking the sample project. I am not so good at java, maybe that's why i couldn't find. Just correct me if I am wrong but I couldn't see any one to one relation inside Cargo Aggregate Root with another Aggregate(Entity). I see **Delivery** ValueObject or **RouteSpecification** ValueObject. And I realize there is a **Location** (Aggregate) but this is also the root object I believe. Can you please give more details if it is possible. – Can Günaydın Mar 01 '23 at 12:38
1

One thing you seem to be missing is that an Aggregate Root is always an Entity. So, just be sure to understand that. Aggregates are just groups of entities, the smallest of which is a single entity (which would then be the aggregate root).

There is no restriction stating that an aggregate cannot have 1:1 relationships, it's just not as common as 1:N relationships. If you do have a 1:1 relationship between an aggregate root and another entity, the two are inextricably linked, despite having separate identities. You've made it difficult to access the child entity directly (you must do so through the aggregate root). Maybe this is what your design needs but most of the time this kind of thing would be modeled as a value object rather than an entity (and as @VoiceOfUnreason notes, copies of data are common things you might include here, such as a copy of the customer's info at the time an order was placed, rather than a reference to the actual customer). Alternately the relationship could be modeled as an ID reference to another aggregate root. This is quite common as well. Don't make your aggregates too big.

I'm hard-pressed to come up with a design in which I would want to have a 1:1 relationship within my aggregate. It's not against any design rules, but most of the time I would prefer to use a value object or a link to another aggregate. If you want to share a bit about what you're trying to model, we might be able to assist with your design further.

Edit (in response to more domain info):

I actually built online ad software (AdSignia was the product name) for Lake Quincy Media, a company my wife and I sold in 2009. I'm quite familiar with this domain.

In any case, you most likely do want to have unique IDs for Client and Advertiser, and you probably want entities for them as well in this bounded context even if most of their state and behavior lives somewhere else. You should consider what you need from these entities in your BC, and use the materialized view pattern to keep your local copy of these entities' details up-to-date with their own BC(s) where they are managed. An example of this is in my Pluralsight DDD course, where Clients, Doctors, Rooms are managed in a separate BC (and application) but the main FrontDesk scheduling app has a local subset of these entities, and they're updated via messaging whenever the source data changes. HTH.

ssmith
  • 8,092
  • 6
  • 52
  • 93
  • Thank you @ssmith. I have edited my question to show the design that i am trying to manage. Hope it was clear. As you say I think it is not so common to model 1:1 relation aggregate root with another entity. I think I would go with linking with another aggregate root for my design. If you have any suggestion on that or you think that is gonna be unnecessary, I would love to hear about it. – Can Günaydın Feb 28 '23 at 18:21
  • The images are broken links, unfortunately. :( – ssmith Mar 01 '23 at 20:30