Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD Read-Only Repositories returning "value objects"

I'm building a small pricing engine but in order to organize the business logic, I'm trying to follow DDD concepts.

I'm facing an interesting situation. To simplify my code, I'm relying on db function to join/process data extracted from various table. For instance, I have a function that will calculate the daily schedules of a "centre". The output of this function is not really an entity (no real id) and the associated repository does not support create/update/delete features.

Similarly, I use a function to calculate the basic resource pricing (list the resource, check the price for each time range...).

In the end, I have the feeling my repository is returning value objects.

As far as I know repositories should return aggregates, themselves containing entities.

Then how do you return "data"/value objects calculated in the DB?

Thx for your help, Sebastien

like image 778
Seb Avatar asked Jan 29 '23 00:01

Seb


2 Answers

In the end, I have the feeling my repository is returning value objects.

That completely makes sense for read-only use cases.

When Eric Evans first described domain-driven-design, he had been working in a design where "the" aggregate interface was used for both reads and writes. So you would have a single repository, which would provide root entities to the application.

However, a few years later Greg Young gave a talk suggesting a different pattern; with read responsibilities and write responsibilities segregated into two objects. For use cases where you are dealing with writes, entities still make sense.

But for reads, you aren't trying to change the mapping of identity to state. So you can support that use case by simply returning a copy of the current state, which is a value.

So you would have one repository that supports your writes, and one or more additional repositories that support your reads.

These days, that pattern is known as Command Query Responsibility Segregation, or cqrs.

In terms of the actual implementation, it goes exactly as you would expect. The repository interfaces that support your read use cases return value objects (objects where the internal state is immutable).

In some cases, it can make sense to have the repository just return a representation. For instance, if your "application" is a web API that needs to return JSON-text, then you could have the repository return the json representation of the object directly, rather than the "value object" taken from the domain model.

like image 119
VoiceOfUnreason Avatar answered Jan 31 '23 15:01

VoiceOfUnreason


Returning value objects or other non-entity data from repository is not a bad thing itsef. For example, when you need count all clients you should not fetch all client entities form repo, repo should provide method which returns an integer (a value object).

But in your case I suppose you miss some domain concepts. It looks like you moved domain logic into DAL. If it is true, please think twice.

Consider placing logic into business layer. In some point of time business code should load all the data, make caclulations (check the prices) and store ready-made data using repo. Like you perform your joins in BL.

like image 38
poul_ko Avatar answered Jan 31 '23 14:01

poul_ko