DDD: solution for references to a non aggregate root
Asked Answered
M

2

13

I have two aggregate roots and two non aggregate root entities:

entity relationships

I know, that the relation D -> B breaks DDD principle.

I heard, that in the most cases the solution is to make the referenced entity a new aggregate root.

But is making B to a new aggregate root really an option if B is a real child of A (B can not live without A)?

Murguia answered 15/11, 2012 at 11:54 Comment(4)
What about D, is it a "real child" of C? Could it be possible to make D an aggregate root on its own and invert the reference? Hard to tell, though, without the domain knowledge...Vacancy
+1 designing aggregates is really situational, a little context would help.Bucentaur
In the real life D is modelled as a relationship entity which stores timed one-to-many releations from C to B. Timed means: B is assigned to C, and this assignment is valid for some time interval. This times releationship between C and B belongs to C as this can not exist without C.Murguia
The domain is energy logistic market. Entity A is Metering point operator (German: Messstellenbetreiber). Entity B are Metering fees (German: Messentgelte) for metering point. Entity C are Metering points (German: Messstelle). Entity D is timed relationship between Metering point and Metering fees.Murguia
B
2

I agree with you, sometimes it just doesn't make sense to separate one entity from its aggregate, because it fits so naturally in it. This is one of the reasons why I'm not totally sold on the "small aggregates" approach that some recommend.

In such a case, what you can do is get a reference to B by traversal of an instance of A instead of getting it directly. After all, if B can't exist without A, there's no reason objects outside of the aggregate should know about a particular B and not know about its A.

Bucentaur answered 15/11, 2012 at 13:8 Comment(7)
I can not get the reference to B be traversing A because I don't know the particular B. This reference D -> B needs to be at least persisted.Murguia
You can persist the information needed to retrieve B via A in D. That way, you can reference A from C and have specific D instances retrieve the specific B instances they need via A.Selfeducated
That means, if I use O/R mapper I can not force integrity constraint on the reference D -> B. Instead of using foreign key to B in D I have to store some other key (likely primary key of D).Murguia
I also believe that using this approach would reduce the performnce because if I need to work with collection of D's I have to fetch the whole A aggregate for each D just to get the particular B.Murguia
Performance concerns could be address by separating your read-models from your domain models.Selfeducated
Also, I don't think you absolutely have to give up foreign key constraints. More details about your use case could shed some light on the issue..Selfeducated
"I can not get the reference to B be traversing A because I don't know the particular B" - of course you don't know it, since you're looking for it. But A should be able to give it to you according to some parameters (time interval and C for instance). Also, I'm not a big fan of relationship entities, especially when they aren't identified domain concepts, so I would get rid of D and use some kind of dictionary to fulfill the need to search by time interval.Bucentaur
S
1

First of all, this isn't DDD thinking, this is RDBMS thinking. In DDD you model business processes as they are in the real world, you don't have one-to-many etc concepts. So forget about DB, foreign keys and so on.

What are your bounded contexts (BC)? Each aggregate is a BC itself so they can have different representation of the concepts EVEN if they are named the same.

If I understand corerctly, it seems that A B C D are part of a single aggregate. That doesn't mean they are defined ONLY in that aggregate and ONLY in that form. However if C is a fully fledged AR in some other BC, it is quite possible that in THIS context to be represented only as an id or a few properties (interfaces are VERY handy for this stuff). So even if they are both named C, they are different, having only the behavior needed by a specific context.

DDD works with a lot of BCs and the models are valid for one BC only. this means that in your app you would have multiple A ,B ,C definitions according to each BC and each definition might be slightly different. This means that there isn't really only one model suitable for all the cases (and I'm not talking about CQRS here, just DDD).

I don't know much about the domain to actually come up with something more concrete. But simply put, try to represent things as they are and as they work in reality.

Seascape answered 17/11, 2012 at 11:18 Comment(1)
Eric Evans talks a lot about one-one, one-many etc. relations when modelling the domain. Also Each aggregate is not its own BC.Deliquescence

© 2022 - 2024 — McMap. All rights reserved.