Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD: Address as an aggregate root?

I’m struggling designing this system where an address is the most central piece of information. Now in this case, an address is not just a few lines of strings. We’re storing municipalities (code, name), district (post code, name), streets (code, name), house number on a street in a specific district belonging to a municipal. It's a very normalized scheme.

So we have the entities Municipal, District, Street and HouseNumber each with relations to each other, defining a complete address for a person (or something else).

Now I have been trying to figure out if it would make any sense having an aggregate root named Address? An Address entity (aggregate root) would then have references to HouseNumber, Street, District and Municipal. Then a person would be associated to an Address.

Strictly speaking this aggregate root is not necessary, but if I don’t have it, I would have to traverse many objects to obtain the full address. Does it make any sense to create an aggregate root based on that argument?

A person will never reference anything but the aggregate root in this case, however the UI might display only Municipalities (when browsing addresses, etc.). Is this a violation of the aggregate root idea?

I would really like your advice and take on this problem. Any help will be much appreciated!


A little update from another discussion about my problem:

There is some invariants needed to be managed in the aggregate. For example; I can't have a house number on a street thats in one district/municipality, where the postal box is in another different district/municipality. So when assigning a post box to an address/person, I need to make sure that they are in the same district.

Also there are some consistency boundaries (if I understood this concept the right way). If I have an address, this must have a house number in a district on a street (in that district). A street can span multiple districts so it's important to ensure that the house number on that street is in the correct district.


Update about designing the aggregate:

A house number is actually the entry point for an address. A house number is associated with a street and a district. So a person is associated to a house number. What I also want to define is if a person has "postal responsibility" for that house number. Introducing the aggregate root Address, makes the person associate with that instead of the house number. In the database, the aggregate Address will contain a 1-1 association to a house number, and the Address has a 1-* to a Person. Where should I store the value indicating that the person has postal responsibility or not? Should I do this in the Address aggregate? Or where would you put it? And the same goes for my entities - where should I indicate if the person has a postal responsibility?

like image 328
Tommy Jakobsen Avatar asked Feb 27 '23 16:02

Tommy Jakobsen


1 Answers

To distinguish if address is value object or entity, ask Yourself a question - if person address changes and 2nd person had same address - will both change? If they both changes - address gets promoted to entity (cause address identity is important and not value).

To distinguish if address is entity or an aggregate root, ask Yourself a question - does address make any sense on it's own or it's always tied to person, is modified through it, deleted together with it? If it's not tied with person but exists on it's own (in model You are modeling and not reality), then address is an aggregate root.


Strictly speaking this aggregate root is not necessary, but if I don’t have it, I would have to traverse many objects to obtain the full address. Does it make any sense to create an aggregate root based on that argument?

No it does not. Technical issues shouldn't mess with Your domain. Entity can work as a 'sub-aggregate', address can hold together municipality, city, etc. and still be just an entity (cause it makes no sense w/o person).

A person will never reference anything but the aggregate root in this case, however the UI might display only Municipalities (when browsing addresses, etc.). Is this a violation of the aggregate root idea?

Presentation shouldn't mess with Your domain too. As far as i see - it's perfectly fine if You are showing only list of entities and hiding aggregates they belong to.


Two persons can be associated to the same address, and if one of them move the other doesn't move automatically.

Question is - how You want to model that moving process?

I see 2 ways:

  1. When person #1 moves, address is modified but address of person #2 is not the same address and hence - is not affected. In this case - address is just an entity.
  2. When person #1 moves, moving process switches address to another one. In this case - address is an aggregate root.

Addresses exists on their own and if a person move to an address, he gets associated with it.

This one means that You want to stick with 2nd way (when address is an aggregate root). It's fine and there is nothing wrong, but You should re-check if address can be demoted to entity cause that would make Your domain model less complex.


And keep in mind - there isn't "The model", there are only "A model"s. You can't model reality to mimic it perfectly, You can only model some part of it to solve specific problems.

This is why it's so hard to answer ddd related questions.
No one knows Your problems You are trying to solve.


If I understand it correctly (http://msdn.microsoft.com/en-us/magazine/dd419654.aspx - the part about aggregates), then whether an address can exist without a person (or other addressee) is irrelevant; the question is whether the address-constituents can exist or be accessed without the address. If they can, Address shouldn't be an aggregate root.

It is relevant. If address can't exist without a person (which is not a case here) - it's inevitably demoted as an entity (cause it makes no sense without person) or value object (if address itself has no identity). Otherwise - You are just introducing unnecessary aggregate root.

It's fine if aggregate root contains references to other aggregate roots (but not entities of other aggregate roots). Therefore - address constituents can be aggregate roots too (Municipality that is referenced in PostOffice) and that wouldn't change if address itself is entity or an aggregate root.

like image 102
Arnis Lapsa Avatar answered Mar 08 '23 06:03

Arnis Lapsa