DAO, Repositories and Services in DDD

拈花ヽ惹草 提交于 2019-12-02 16:45:45
Magnus Backeus

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.

Enrico Sanguin

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!