DDD Aggregates and Value Objects

I would like to ask a question about DDD functions. Suppose we have two aggregates, and each of them contains the address of the object-object. According to Eric Evans DDD, we must isolate the aggregates from each other, so the aggregate root of the first aggregate cannot have a link to the address. Honestly, for me this does not make sense, so the question is how to resolve this situation? Which unit should contain the address?

thanks

+4
source share
3 answers

You can have this using the same value object. But do this only if aggregate roots exist in the same limited context and therefore have the same meaning for both aggregates. If aggregates exist in different limited contexts, then there are 2 separate and duplicate ones. The leak of one limited context refers to another, to which Eric is trying to fight.

In most cases, problems of an object with objects and values ​​are reduced to the fact that people have problems with data duplication. We were so trained to think in the 3rd normal form of one canonical model. DDD is struggling with the inevitable complexity that arises from forcing duplication where necessary, and allows concepts that were once considered one of many.

Hope this helps

+9
source

A Value object is an object that describes some characteristics or attribute, but does not contain the concept of identity.

Since it does not have a conceptual identity, you cannot “link” or “have a link” to it. You can only "contain" it. Suppose you have a user and the user is of age. Age is an object of value. If John is 25 years old, and Jane is also 25, they do not refer to the same age. Jonh Age is simply equal to Jane Age. Therefore, if your address is truly a Value object, you are not breaking any Aggregate boundaries. Your common roots just have the same address. Even if you have a technical java / C # reference for Address, it doesn't matter, since the Value object is immutable most of the time.

It is difficult to answer your question without knowing what area you are working in. But usually the address does not have to be a Value Object. Eric Evans mentions in his book that postal services and delivery route domains will treat the address as an entity. The electrical company that sends the technicians must understand that the two service calls from 123 Elm St actually come from the same address, and he only needs to send one specialist. The address or "Home" in this case is the entity.

+8
source

Aggregates are associated only with DATA MODIFICATION . No two units should be allowed to change the same data. Because the Value object is immutable, it prevents this scenario. Therefore, for two or more aggregates it is quite normal to use the same Value object, since it is a read-only data structure, and the aggregate does not care about the reading model.

Address a = new Address("1111 ABC Ave."); person.setAddress(a); letter.setAddress(a); person.getAddress().change("2222 XYS Ave.") // THIS IS ILLEGAL SINCE Address is a VO (immutable) 

The above will never happen for the address, and therefore it is not dangerous to share, because you do nothing with the Address of the person, you will never affect the letter, so the letter still protects its own invariants.

If an “Address” is assigned an entity, you cannot use the same address in both entities, since the above code will make the letter vulnerable to changes per person, and this will break the border, and this will not allow the letter to control its invariants.

This is the whole point of Aggregate Roots, it also models things in such a way as to limit side effects. If you define very clear boundaries for the modification, it will be easier to work with, and you will prevent potential harmful unexpected effects.


I will add one more thing. As mentioned in another answer, you want the other restricted context to have a different type of address. The reason for this is that the details that you need for an address in one context do not necessarily match what you need in another. Thus, having two types of addresses, one for each context, you highlight the needs of one of the needs of the other.

Say what you need:

 Address { Number; Unit; Street; State; Country; PostalCode; } 

But for the location you need:

 Address { Number; Unit; Latitude; Longitude; } 

DDD will say call them both addresses, but bind them to a different context. Therefore, although they all speak the language as an address, their specific data and behavior may differ depending on the context you are talking about. What you absolutely must not do is create a kind of MonsterAddres that will contain all the possible data and behavior of all contexts in your domain and have this type of address used in all contexts.

Please note that we are talking about the model in your application, it’s good to store all the address data in the Monster address table, but when modeling your application you should separate this into the logical restricted context that appears in your domain and the ubiquitous language that it uses.

+2
source

All Articles