Why are repositories only used for aggregates in Domain-Driven Design?
Asked Answered
P

2

15

In DDD, repositories are used to perform serialization and de-serialization of aggregates, e.g. by reading and writing to a database. That way, aggregates can contain purer business logic, and won't be coupled to non-domain-specific persistence strategies.

However, I wonder why repositories are always described as being used for aggregates specifically. Isn't it equally motivated to use it for all entities?

(If this is only a matter of the fact that all plain entities can be seen as aggregate roots with zero children, please notify me of this, and the question can be buried.)

Poetize answered 27/9, 2017 at 15:41 Comment(2)
Your last sentence is correct. I read the book and didn't get the connection that a single entity can be an aggregate root with no children and therefore is also a viable candidate for being stored by a repository.Lemniscus
In agreement with all. An entity has a life cycle and identity of its own. It can, therefore, be retrieved and operated on. Another way to look at it is that a repository returns an entity. That entity can either aggregate other objects or not. As for what a repository retrieves: I'm pretty sure the blue book has an image on the inside cover that indicates a repository loads Entities and/or ARs.Giustino
S
23

I wonder why repositories are always described as being used for aggregates specifically. Isn't it equally motivated to use it for all entities?

Because aggregates are the consistency boundaries exposed to the application layer.

Which is to say that, yes, the repositories are responsible for taking the snapshot of state from the data store, and building from it the graph of entities and values that make up the aggregate.

The API of the repository only exposes an aggregate root, because that defines the consistency boundary. Instead of allowing the application to reach into an arbitrary location in the graph and make changes, we force the application to communicate with the root object exclusively. With this constraint in place, we only need to look in one place to ensure that all changes satisfy the business invariant.

So there's no need to develop a repository for each type of entity in your model, because the application isn't allowed to interact directly with the model on that fine a grain.

Put another way, the entities within the aggregate are private data structures. We don't allow the client code to manipulate the entities directly for the same reason that we don't implement lists that allow the clients to reach past the api and manipulate the pointers directly.

In , you do see "repositories" that are used for things other than aggregates -- repositories can also be used to look up cached views of the state of the model. The trick is that the views don't support modification. In the approach that Evans describes, each entity has one single representation that fulfills all of its roles. In CQRS, and entity may have different representations in each role, but typically only a single role that supports modifying the entity.

Shoshone answered 27/9, 2017 at 16:46 Comment(3)
For example: order and line items for an aggregate. If I want to change an item status I have to query the order and its line items by order Id, change item status through order entity and finally call aggregate repository to save. am i right ?Geographical
another question is can i update status of order directly by order id (by repository) without getting order entity, update status and calling repository to save new update? thanksGeographical
Excellent answer, +1 for mentioning CQRS "read-only" repositories.Spear
A
7

In DDD there are two kind of entities: Aggregate roots and nested entities. As @VoiceOfUnreason answered, you are not allowed to modify the nested entities from outside an Aggregate so there is no need to have a repository for them (by "repository" I'm refering to an interface for load and persist an entities state). If you would be allowed, it would break the Aggregate's encapsulation, one if the most important things in OOP. Encapsulation helps in rich domains, with lots and lots of models where DDD is a perfect fit.

Ardy answered 27/9, 2017 at 18:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.