DDD: Address as a cumulative root?

I am trying to develop this system where the address is the most central part of the information. Now in this case, the address is not just a few lines of lines. Municipalities (code, name), district (zip code, name), street (code, name), street number in a specific area belonging to the municipality were saved. This is a very normalized scheme.

Thus, we have the entities Municipal, District, Street and House number, each with a relationship to each other, which determines the full address for a person (or something else).

Now I was trying to figure out if it makes sense to have a common root named Address? After that, the address object (aggregate root) will have links to HouseNumber, Street, District and Municipal. Then the person will be associated with the address.

Strictly speaking, this aggregate root is not needed, but if I do not have it, I will need to cross many objects in order to get the full address. Does it make sense to create a composite root based on this argument?

In this case, the person will never refer to anything other than the aggregate root, however, only the municipalities can display the user interface (when viewing addresses, etc.). Is this a violation of the general idea of ​​the root?

I would really like your advice and solve this problem. Any help would be greatly appreciated!


A small update from another discussion of my problem:

Invariants must be controlled in the aggregate. For instance; I cannot have a house number on a street that is in one district / municipality, where the mailbox is in another district / municipality. Therefore, when assigning a mailbox to an address / person, I need to make sure that they are in the same p.

There are also some boundaries of the sequence (if I understand this concept, right). If I have an address, he should have a house number in the county street (in this area). A street can cover several areas, so it is important that the house number on this street is the correct r.


Update on creating an aggregate:

The house number is actually the entry point for the address. The house number is associated with the street and the area. Thus, the person is associated with the house number. I also want to determine if a person has a "postal responsibility" for this house number. Presenting the general address of the root, a person contacts him instead of the house number. In the database, the aggregate address will contain the association 1-1 with the house number, and the address has 1 * for the Person. Where should I store a value indicating that the person has a postal responsibility or not? Should I do this in address aggregation? Or where would you put it? And the same applies to my entities - where should I indicate whether a person has postal responsibility?

+4
source share
3 answers

To distinguish whether an address is an object of value or essence, ask yourself the question - if a person changes the address and the 2nd person has the same address, will both change? If they both change, the address gets promoted to the entity (the reason is the identity of the address, not the value).

To distinguish whether an address is an entity or an aggregated root, ask yourself the question - does the address really make any sense on it or is it always attached to a person, is it modified, deleted with it? If it is not connected with the person, but exists on it own (in the model you are modeling, not reality), then the address is the aggregate root.


Strictly speaking, this aggregate root is not needed, but if I do not have it, I will need to cross many objects in order to get the full address. Does it make sense to create a composite root based on this argument?

No no. Technical questions should not be associated with your domain. An entity can act as a “sub-aggregate," an address can contain a municipality, a city, etc. And still be just an entity (because it doesn’t make sense without a person).

In this case, the person will never refer to anything other than the aggregate root, however, only the municipalities can display the user interface (when viewing addresses, etc.). Is this a violation of the general idea of ​​the root?

The presentation should also not conflict with your domain. As far as I can see, this is great if you show only the list of entities and hide the aggregated elements to which they belong.


Two people can be associated with the same address, and if one of them moves the other, it does not move automatically.

Question: how do you want to simulate this movement process?

I see two ways:

  • When person # 1 moves, the address is changed , but the address of person # 2 does not match the address and therefore is not affected. In this case, the address is just an object.
  • When person # 1 moves, move the switch to another. In this case, the address is the cumulative root.

Addresses exist on their own, and if a person moves to an address, he will be associated with him.

This means that you want to stick to the 2nd method (when the address is an aggregated root). This is normal and there is nothing wrong, but you have to check if the address can go down to the entity level, which will make your domain model less complicated.


And keep in mind - there is no "Model", there is only a "Model". You cannot simulate reality to accurately simulate it. You can model only part of it to solve specific problems .

This is why it is so difficult to answer questions related to ddd. No one knows your problems that you are trying to solve.


If I understand correctly ( http://msdn.microsoft.com/en-us/magazine/dd419654.aspx - part about aggregates), then whether the address can exist without a person (or another addressee) does not matter; the question is whether component addresses can exist or be available without an address. If they can, the address should not be an aggregated root.

This is relevant. If the address cannot exist without a person (which does not apply here) - it will inevitably be demoted as an object (because it does not make sense without a person) or an object of value (if the address itself does not have an identifier). Otherwise, you enter the unnecessary aggregated root.

It is good if the aggregate root contains references to other aggregate roots (but not the entities of other roots of the aggregate). Thus, addressable components can also be aggregate roots (the municipality referenced in PostOffice), and this will not change if the address itself is an entity or aggregate root.

+6
source

A collection, in my opinion, should be created if

  • there is a deterrence relationship with associated objects
  • objects The aggregate is stored in a database, and only the root should be accessible through queries. other objects must be obtained through workarounds.
  • and you have invariant rules that need to be followed evenly across the contained objects.

your script does not seem to satisfy either one or the other. Therefore my opinion is not

Also read this post and reply to it: DDD: Aggregate Roots

+1
source

If the address should be a separate entity, it should not be driven by technical problems.

The way you talk about the address tells me that this is a separate entity consisting of the parts that you mentioned.

The fact that the address is preserved, even if it is not attached to the Person or another class, is also the key to the fact that it must be its own essence.

In addition: the address can be used not only as Person, but also by other things (classes). Do you really want to burden every class that can have an address in order to deal with how to form it from its constituent parts?

The only fact that you are talking about an address as a concrete concept is enough to make it a separate class. Even if the address only exists as long as it is bound to another class, it would be advisable to create a separate class, perhaps a nested class in this case, just to separate the logic associated with the address from the logic related to other attributes person.

Update

If I understand correctly ( http://msdn.microsoft.com/en-us/magazine/dd419654.aspx - part about aggregates), then whether the address can exist without a person (or another addressee) does not matter; the question is whether component addresses can exist or be available without an address. If they can, the address should not be an aggregated root.

On the one hand, the address should be a combination of its components. But the component parts of the address appear to be independent of the address and can exist without it. After all, a municipality or a street can exist without the presence of a “door”. So, I would say that this disqualifies Address as the cumulative root in terms of DDD.

Update As Tommy mentioned (see Comments): The best question would be "Will the system ever manipulate the street / municipality directly or will the whole address always be?"

I would think that selecting a municipality from a list to create an address is not a “direct manipulation” when it is always performed in the context of building an address. Similarly, I would not consider this list of municipalities “direct manipulation” if it is maintained only at the address.

Update As Arnis points out, is there an address that can exist independently of the Person (or other entity), to the extent that it dictates, is the address an entity in its own right. As I understand it now, only entities can be aggregate roots.

0
source

Source: https://habr.com/ru/post/1315581/


All Articles