Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependencies between domain object, factory and repository

Ok i read many things about the repository pattern, including Fowler's book. I know pretty good what it is and what it does, however what i'm not quite sure yet is how it is called by factories and/or domain objects.

What I understood is that the repository is supposed to act like an in-memory collection of domain object, and the factory is the class in charge of the instance creation: new myDomainObject()

With that in mind, it seems obvious that the repository will need a reference to the factory to create new objects from the data source queries. (Repository -> Factory)

Domain objects also need a reference to the factory in order to create new objects.

My dilemma is when a domain object want to retreive an existing object, should it call the repository or the factory ? If it calls the repository directly (Domain -> Repository -> Factory), than it would need to have both the references to the factory and the repository, which seems too much to me, but is it that bad ?

On the other hand, if it calls the factory like factory.CreateObjectWithId(id), then the factory would have to only redirect the call to the repository repository.GetById(id), and this last would call another method on the same factory for object creation (if it is not already in memory) factory.CreateObject(dataset), so that leads to a circular reference: Domain object -> Factory <--> Repository, which again does not seems really a good thing to me.

So in your opinion which of these options is better ? or is there another option ?

like image 235
Jonathan Avatar asked Dec 16 '15 13:12

Jonathan


People also ask

Are factories part of the domain?

Factories have nothing to do with the domain of an organisation, but they do form an important part of the domain of an application. It is the domain of the application that is responsible for creating and working with Domain Objects.

Can domain services use repository?

Yes, a domain service can access repositories.

What is Factory in DDD?

A factory is a tactical pattern used in the DDD world. It helps us create complex objects. It is important to keep in mind that we should only implement this pattern when the instantiation of an object is complex.

What is repository in DDD?

In DDD, a repository is an objcect that participates in the domain but really abstracts away storage and infrastructure details. Most systems have a persistent storage like a database for its fully functioning. Applying repositories happens by integrating and synchronizing with existing aggregate objects in the system.


1 Answers

You've got the basics right. The misunderstanding you have seems to come from your assumption that domain objects should be the primary clients of repositories. This is not the case, you should only access the repositories from domain objects if there is no other way. Try to avoid it in general.

So the missing piece in your equation is the thing that acts as primary client of the repositories.

Enter: The Application Service

An application service is a service that contains use case logic (as opposed to domain logic). It performs input validation, implements access management, and is responsible for transaction control.

This means the app service would use a repository to load an aggregate from the DB, do something with it, and then make sure the changes are persisted (i.e. commit the transaction).

Depending on the style of repository that you're using, saving an aggregate back to the DB is slightly different:

  • With collection-style repositories, the app service normally uses a unit of work to track and commit the changes.
  • With command-style repositories, the app service passes the aggregate back to the repository after performing the business operation on it.

Factories and Repositories

Regarding your questions about the relationship between factories and repositories, I think this answer of mine provides the answer to your question as well. The basic gist of it is:

  • Use the factory from the repository to avoid duplicating the instantiation logic of an aggregate.
  • Make sure the concepts are clear from the outside, i.e. don't expose the "reconsitution interface" of a factory that the repository sees to other classes. This is best achieved by following the Interface Segregation Principle.

Using Repositories from the Domain

If you constantly need to query other aggregates from the DB to perform business tasks in the domain layer, this is an indication that your aggregate boundaries could be wrong.

Of course, there are cases where the aggregate boundaries are fine, and the required objects cannot be passed to the domain object as parameter. In that case, it can make sense to use a repository from the domain. Be sure to try other approaches before doing this. In any case, only depend on a repository interface, never on a concrete repository implementation.

like image 128
theDmi Avatar answered Sep 22 '22 13:09

theDmi