简体   繁体   中英

Domain Driven Design repository for child aggregate entity

After reading about DDD and Aggregates and taking a look at some StackOverflow posts like this

Update an entity inside an aggregate

Some doubts about aggregates' responsibilities and repositories come to me.

For example, if we supposed that we have user and address entities and one invariant that says that one user should only have a maximum of 3 addresses conforming by this way and Aggregate with those domain rules.

Taking into account this, it is supposed that when you conform that aggregate the access to the addresses child entity inside the user class will be always through user class methods, some methods like this will exist:

user.registerNewContactAddress("street blabl") user.updateContactAddress(address_id,"street blablb")...

In this basic scenario my questions are:

1) It is supposed that should NOT exist an address repository, but, is it a mandatory rule or discouraged rule in all the cases?

I am thinking about the need to list all the addresses in the system, for example, obviously is more efficient to use an address repository that iterates across all the users and retrieves all their addresses.

Or, for example, an user case that looking for "near" address.

So, maybe an address repository with "only" methods "findAll" and "findXX" fit into DDD philosophy? Leaving the insertion and deletion of addresses managed by user Aggregate watching the invariant?

2) What happens if, for example, instead of having a maximum of 3 addresses we have, 30.000 ( just a stupid case, I know, I'm sorry).

In this case, should we conserve the user.changeAddress(address_id,"street blablb") method? I guess that it will become a little bit inefficient to retrieve the user and, in memory, iterate across all his addresses, so, it is another case where I see that maybe a direct call to address repository by ID is better.

Thanks

The use case you are describing is about reading all addresses of a user. For read operations it is not only allowed to have specific query operations that bypass the access of data through aggregates. It is even encouraged. See also this answer to a similar question.

Aggregates and repositories are optimized for write operations where business invariants need to be kept in tact. To query data that is needed for read operations only (eg displaying data) the domain model, and thus aggregates and repositories, should be bypassed to optimize for reading the required data. If needed, this could even mean to have raw queries if an ORM does not provide the required performance.

Note : if you need to be able to manipulate actresses outside the context of a user (standalone) you might have missed a separate address aggregate. In that case I would rather model Address as some reference type value object inside User , eg AddressId. Unless you need more data of an address in the context of the business logic executed by the User aggregate.

And another note : in general, I would consider an Address to be a value object rather than an entity, unless you really share the same address "entity" across several users, which could be rather unlikely or necessary. As the properties of an address alone allow to tell one address from another I would not see any need for an identity making it an entity.

Value objects are usually modelled as part of the aggregate. In a relational database this could mean they get distributed across columns of the same table or for collections of value objects this is often done as serialized data, such as JSON. This also reduces potential performance worries as everything is queried from the same table.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM