Excerpted from Domain-Driven Design Book
Definition: A Repository is a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects.
Problem: A client needs a practical means of acquiring references to preexisting domain objects. If the infrastructure makes it easy to do so, the developers of the client may add more traversable associations, muddling the model. On the other hand, they may use queries to pull the exact data they need from the database, or to pull a few specific objects rather than navigating from
Aggregate roots. Domain logic moves into queries and client code, and the
Entities and
Value Objects become mere data containers. The sheer technical complexity of applying most database access infrastructure quickly swamps the client code, which leads developers to dumb down the domain layer, which makes the model irrelevant.
In other words: A subset of persistent objects must be globally accessible through a search based on object attributes. Such access is needed for the roots of
Aggregates that are not convenient to reach by traversal. They are usually
Entities, sometimes
Value Objects with complex internal structure, and sometimes enumerated Values. Providing access to other objects muddies important distinctions. Free database queries can actually breach the encapsulation of domain objects and
Aggregates. Exposure of technical infrastructure and database access mechanisms complicates the client and obscures the
Model-Driven Design.
Solution: For each type of object that needs global access, create an object that can provide the illusion of an in-memory collection of all objects of that type. Set up access through a well-known global interface. Provide methods to add and remove objects, which will encapsulate the actual insertion or removal of data in the data store. Provide methods that select objects based on some criteria and return fully instantiated objects or collections of objects whose attribute values meet the criteria, thereby encapsulating the actual storage and query technology. Provide
Repositories only for Aggregate Roots that actually need direct access. Keep the client focused on the model, delegating all object storage and access to the
Repositories.