45

After reading several articles, I am starting to understand the difference between DAO and Repositories, but I find myself in trouble trying to understand the difference between Repositories and Services.

For putting in short terms, in the OO paradigm:

  • DAO : Class that contains the basic CRUD operations for one entity class. It has the necessary code to get or retrieve things of the underlying persistent storage system. Generally speaking, the methods receive object entities as parameters, except in the retrieve method where using a type of the Identifier is valid.

  • Repositories : In a higher level of abstraction.. as generally I have read is a kind of place where put code that handle operations over aggregate objects (objects that have child objects). It uses the DAOs to retrieve objects from the database, and in the end it exposes an interface in the domain "business" language. (But again, I think it is very valid to use data types of ids). Example : A very simple addSomething where something is a child object of the parent whose instances, btw, are managed as a whole by the Repository.

  • Services : Again, it is in a higher level of abstraction. To my humble point of view they are a good place to connect two classes that do not share parent-child relation, but is as far (in abstraction terms) as Repository. Example : The method transferCash between two bank accounts.

So, that's are my readings about, but I am asking here the above thoughts are right or not. Or how I should think. Or something that points me to really understand the difference of all this concepts.

Some of the sources :

Community
  • 1
  • 1
Victor
  • 3,841
  • 2
  • 37
  • 63
  • 5
    Have you read http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215 or http://www.infoq.com/minibooks/domain-driven-design-quickly ? Nothing compares to getting knowledge from the source... – guillaume31 Nov 13 '13 at 10:03
  • No i haven't yet, i doesn't have much time. Well, i have read something about DDD quickly, but i thing i need more time... is a TODO, yeah i know. – Victor Nov 13 '13 at 13:42
  • I read DDD quickly and get some ideas, into my last pet proyect (https://github.com/vituchon/escobita). DDD doesn't solve anything but is a great resource that show another vision about how you may structure your code for solving big aspect of a system that handles CRUD operations over complex entities. **The big problem** is translating a search query from user's domain (problem) into programs's domain (solution), I mean, coding so called "criteria" abstraction (the same name is used in Hibernate and other visions or approachs) – Victor Jan 25 '23 at 14:22

3 Answers3

37

Repositories are - like you say - an abstraction. They originate from Martin Fowler's Object Query Pattern. Both Repositories and DTOs can simplify database persistence by mapping persisted data to equivalent collection of entity objects. However, Repositories are more coarse-grained than DAOs by providing control of an entire Aggregate Root (AG) often hiding a lot of internal state from the client. DAO's on the other hand can be as fine-grained as being dedicated to a single entity object. For both Repositories and DAOs it is common to use Hibernate or other Object/Relational Mapping (ORM) Frameworks instead of writing your own implementation.

Typically, services can reside in a Service Layer and can act both as a functionality facade, anti-corruption layer and coordinator for caching & transaction. They are often a good place to conduct logging. Services coarse-grained and usecase-oriented, e.g. Service.updateCustomerAdress() or Service.sendOrder(). Repositories can be too fine-grained for clients to consume, e.g. Customer.add(…), Order.modify(…).

Repositories and DAOs have the same purpose - to persist data permanently. Services on the other hand should be ignorant of persistence and have no knowledge about your database. They usually work tightly together with domain services, repositories, domain core.

Community
  • 1
  • 1
Magnus Backeus
  • 2,242
  • 17
  • 24
  • Thanks Magnus, i would like to see the complete method signature of repositories and services, in order to understand in what abstractions thinks. BTW also about a DAO, it shall be good. – Victor Nov 13 '13 at 13:40
  • 1
    Take a look at http://sourceforge.net/projects/dddsample/files/ or http://microsoftnlayerapp.codeplex.com you will find both repositories and services.. just start visual studio solution and search for "repository" and "service" you'll find plenty. – Magnus Backeus Nov 13 '13 at 23:13
  • 1
    After long time, i have review this topic, i and think this shall be accepted as correct answer. Thanks for the time guys! All of you! – Victor Jun 11 '15 at 14:28
  • I'm interested how "Services on the other hand should be ignorant of persistence" if they "can reside ...for caching & **transaction**". Isn't transaction part of persistence? – Sabine Mar 04 '17 at 19:49
  • @Sabine true. They should not be aware of persistance or caching. BUT cross cutting concerns like logging, security, transaction, some-kind-of validation etc are usually functionally and operating in service layer. This is here we want to start a saga or a transaction. But the service method/command itself is dependent on an abstraction or decorated. I prefer both. So awareness of what kind of transaction this is, or what kind of cache we use, is moved away through Inversion of Control pattern – Magnus Backeus Mar 16 '17 at 14:07
17

Repositories are interfaces for storing and retrieving Aggregate Roots (AR), not single Entities. You have one Repository for each AR of your Domain Model.

As per Fowler's Repository Pattern, repositories act like in-memory objects collection and this is one of the main differences comparing them to DAOs.

Repositories interfaces are a means for Domain Model's client (and thus are part of the Domain Model) to get start working with the Domain Model. Client's are intended to get an AR instance from a Repository, call some method on it, which usually modify its internal state, and then store it back to the Repository.

Community
  • 1
  • 1
Enrico Sanguin
  • 433
  • 3
  • 12
  • How did you come to conclusion that Repositories belong to the Domain Layer? Is it your personal conclusion or had Evans or other DDD guru stated that? I just had a question which layer Repositories belong (domain or persistence). And you occasionally answered it. And if they belong to domain layer, how to we prevent storage technology concerns from leaking into the domain layer (which is a clear goal of layered architecture in DDD)? Sorry for off-topic. – Alexey Aug 17 '19 at 22:56
  • 1
    @Alexey Repositories interfaces belongs to the domain model not their implementations. You can even see that in Evans open source example project. – Enrico Sanguin Aug 20 '19 at 22:44
4

I'm not sure what "DAO" even is. Repositories are an abstraction for loading entities. You should be able to Get an entity and Save one, that is it. No querying. If you want to query some data, write a query (maybe even within an MVC action method, or with the simplest of simple abstractions allowing some SQL to be executed and some DTOs returned that can be rendered straight into the HTML).

Services on the other hand are tricky. For a start the term is overloaded. "Application Services" as defined by the DDD book by Eric Evans exist because objects in the Domain Model are not allowed to access infrastructure concerns like databases, messaging, caching etc. They need all of that stuff done for them and handed to them on a plate, and Application Services do just that. Application Services, for their part do not contain any logic. I would not expect to see ICustomerService.ChangeAddress() do anything other than:

  1. Load the Customer entity.
  2. Call Customer.ChangeAddress(newAddress) <- this encapsulates the domain logic
  3. Save the customer.
  4. Perhaps publish some events.

If you have a service that is loading a customer, setting it's Address property and saving it, then that service is actually a Transaction Script and the Customer is a DTO. Meaning you definitely have a leaky abstraction and likely have an anaemic domain model. Domain model objects should not have public setters, and when DDD is combined with CQRS, your domain model may not even have any public state at all beyond the main entity ID values.

Neil Barnwell
  • 41,080
  • 29
  • 148
  • 220
  • "No querying.": it conflicts with Edward Hieatt and Rob Mee definition for repositories: "(repository) Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects." – rdllopes Feb 27 '15 at 11:34
  • You won't want to query *domain objects*. You want to query *data* and project to whatever shape you need. If you're querying for, retrieving, hydrating etc proper domain objects just to put a few of their properties on a UI, you're wasting a lot of effort. – Neil Barnwell Mar 02 '15 at 09:22
  • Don't forget, your quoted definition for repositories doesn't mention *querying*. It simply states a "collection-like interface for accessing". Apart from LINQ in .NET, which is only extensions anyway, how many collection-like interfaces support querying? (for-each doesn't count). – Neil Barnwell Mar 02 '15 at 09:24