Domain Driven Design issue regarding repository

2020-07-24 04:37发布

问题:

I am trying to implement the DDD so I have created the following classes
- User [the domain model]
- UserRepository [a central factory to manage the object(s)]
- UserMapper + UserDbTable [A Mapper to map application functionality and provide the CRUD implementation]

My first question is that when a model needs to communicate with the persistent layer should it contact the Repository or the mapper? Personally I am thinking that it should ask the repository which will contact the mapper and provide the required functionality.

Now my second concern is that there should be only one repository for all the objects of same class, so that means I will be creating a singleton. But if my application has lots of domain models (lets say 20), then there will be 20 singletons. And it don't feel right. The other option is to use DI (dependency injection) but the framework I am using (Zend Framework 1.11) has no support for DIC.

My third

回答1:

  • UserRepository [a central factory to manage the object(s)]

In DDD Repository is not a Factory. Repository is responsible for middle and end of life of the domain object. Factory is responsible for beginning. Conceptually, persisting and restoring happens to the domain object in its middle life.

  • UserMapper + UserDbTable [A Mapper to map application functionality and provide the CRUD implementation]

These classes do not belong to a domain layer, this is data access. They would all be encapsulated by repository implementation (or would not exist at all if you use ORM).

My first question is that when a model needs to communicate with the persistent layer should it contact the Repository or the mapper? Personally I am thinking that it should ask the repository which will contact the mapper and provide the required functionality.

Model does not need to communicate with persistence layer. In fact you should try to make your model as persistence-agnostic as possible. From the perspective of your domain model, Repository is just an interface. The implementation of this interface belongs to a different layer - data access. The implementation is injected later, somewhere in your Application layer. Application layer is aware of persistence and transactions. This is where you can implement Unit Of Work pattern (that also does not belong to domain layer).

Now my second concern is that there should be only one repository for all the objects of same class, so that means I will be creating a singleton. But if my application has lots of domain models (lets say 20), then there will be 20 singletons.

First of all you can have more than one Repository for a given domain object. This is what happens most of the time anyway because you want to avoid 'method explosion' on your Repository interface. Secondly singleton Repository is a bad idea because it would couple all consumers to a single implementation which, among other things, would make unit testing hard. Thirdly, there is nothing wrong with having 20 or more Repositories, in fact the more focused classes you have the better, see SRP.

UPDATE:

I think that you are confusing regular Factory pattern and DDD Factory. In DDD terms, when the object is restored from the database it already exists conceptually (even though it is a new object in memory). So it is a responsibility of the Repository to persist and restore it. DDD Factory comes into play when the complex domain object begins its life - whether it would be a long lived object (saved in db) or not.



回答2:

Answering your second question. The ZF1 way would be to create a singleton per object class. You could have a factory/registry that creates these for you and returns the previously created one when you ask for an already created one. Alternatively, if you are using PHP 5.3, use a DI container such as Pimple or Zend\Di.