Search code examples
architecturerepository-patternddd-repositories

Queries in repository pattern which are not related to the collection interface


Repository represents collection interface. You can store, delete and find objects using repository.

But i often see interface of repository contains methods encapsulated complex queries which are not related to collection interface. For example: method for complex calculation of statistic which returns some dto. Or some checks using mysql which return boolean, like "userHasSomething"

It seems a Repository is not the best place for these methods.

Should a Repository strictly represent an interface of collection or it should to do all jobs related to the storage?

Where to place these queries?


Solution

  • Frankly, all this repository stuff is opinion based.

    Following is how Martin Fowler defines it:

    Repository

    A system with a complex domain model often benefits from a layer, such as the one provided by Data Mapper (165), that isolates domain objects from details of the database access code. In such systems it can be worthwhile to build another layer of abstraction over the mapping layer where query construction code is concentrated. This becomes more important when there are a large number of domain classes or heavy querying. In these cases particularly, adding this layer helps minimize duplicate query logic.

    A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.

    As you noted in your question:

    But i often see interface of repository contains methods encapsulated complex queries which are not related to collection interface.

    In my opinion, in DDD context, repositories should work the way you are explaining (collection interface) in your question. Rest is the business logic and should move to either Domain Model or Services.

    Theory remains theory; purists follows it strictly. Most important above all is business needs.

    Patterns are good and one must follow those. Those are build by experts based on their years of experience. One should not hesitate to use it if same problem is at hand.

    Patterns like repository are bit broader than GoF patterns. That makes repository bit opinion based. Further, repositories are widely used outside the DDD context as well. That further adds up the opinions.

    It seems a Repository is not the best place for these methods.

    If you think so and you have better place in your design for those methods, go ahead and move those methods to that place. If your design tell you that repository is the best place for those method, do not hesitate to use it.

    Where to place these queries?

    Up to you. Focus on the problem in hand, focus on your design, focus on your business needs. Do not add unnecessary complexity in your code just to follow the pattern correctly. What is the use of the pattern if it creates new problems by fixing the promised one?