1

I have been reading about what people said regards repositories location (in which layer) in DDD context and found things that don't feel right to me. Example:

Is true that "in terms of more "classical" DDD, yes domain objects are typically not allowed anywhere outside of the domain."

from here

Can any body point me to some other reference that state something like that? or at least an explanation why?

What feel right to me is that some repositories belong to Domain Layer. As Evans said, repositories must mainly used to return Aggregates to avoid:

...breach the encapsulation of domain objects and AGGREGATES...

and follow:

...A REPOSITORY lifts a huge burden from the client, which can now talk to a simple, intention-revealing interface, and ask for what it needs in terms of the model...

so if Aggregates is a Domain Object and is returned by some repositories that lead us to have repositories that must know how to reconstruct those Domain Objects, such repositories implementations will have a very close relationship with others parts of Domain Layer like simple Aggregates class definition or reconstruction factories.

These thoughts lead me to the second question, is habitual that App Layer retrieve Domain Object from the repositories outside a Naked Object context? I feel that yes, and that the use of Data Transfer Objects is just needed when performance or another specific reason justified it, but if we design the Domain Layer interface in a way that knowledge leak is avoided (just exposing Domain Objects and Domain Services needed to the App Layer and not the internal ones), we will be safe. Has sense that line of thought?

I said some in the previous paragraphs cos I think that some repositories could be not so tied to the Domain Layer, I talking about repositories to access some kind of values or enumerable objects or in general, objects that are no so tied to the Domain. Evans talk about too, he considered that some times have sense a global search, and that such global search will not get any harm to the a design.

Another reason to the existence of repositories is avoid:

Exposure of technical infrastructure and database access...

and

decouple application and domain design from persistence technology, multiple database strategies, or even multiple data sources.

This other goals of the repository pattern let me to think at first that repositories can't be on the Domain Layer, that is contradictory with what I already said.

At the end, I think that exist two type of repositories if we classified them accord to its layer location:

1-One that belong to Infrastructure Layer witch an interface returning non Domain Layer objects, avoiding that lowest layers depend on highest layers. This kind of repositories will be used by Application Layer mostly to retrieve some kind of VALUES/ENUMERABLE objects.

2- The other type of repositories return Domain Objects and reside into the Domain Layer. This type of repositories depend of interfaces provided by the Infrastructure Layer for basically decouple application and domain design from persistence technology while allow Application Layer talk with the domain in an intention-revealing interface, and ask for what it needs in terms of the model. These kind of interfaces provided by the Infrastructure could be expressed in terms simple and raw data contracts and could be seem like a second form of repository through which Domain Layer ask the data (to the Infrastructure Layer) it need to form a Domain Object and reply a request from the Application Layer. Seem to me that in practice I can end with duplicate code in cases where Domain Object are very simple and similar in form to how they are stored in database. I will appreciate any comment about these problems and how the code is organized to solve them in the context of DDD.

I will thank critics to these thoughts, mainly those whose highlight its soft points ;)

Here a diagram of what I'm talking about

enter image description here

EDIT:

The more I read about this, the more I think that this distinction is very important and could get some understanding to the community. For example what is described hereis Infrastructure Repositories (type 1 in what I wrote) while here describe Domain Repositories (type 2 in what I wrote).

Even more, I think that part of the fight like this one are promoted for the lack of the distinction I made here.

Community
  • 1
  • 1
  • The dependences between Application/Infrastructure and Domain/Infrastructure should be inversed. In this case, all infrastructure components are implementing application/domain concepts. This is reasonable when considering application and domain are relativelty stable. – Yugang Zhou Oct 21 '13 at 02:38
  • Thanks @Hippoom. I put that rows to signal a reference/dependency from Application code to interfaces implemented in the Infrastructure Layer, the same with Domain/Infrastructure. I mean, App Layer have references to interfaces implemented in the Infrastructure Layer, then App ---> Infrastructure, the implementation of such interfaces in the Infrastructure Layer don't become the Infrastructure Layer in a layer that depend on App, the same with Domain/Infrastructure. May be I don't get what you mean;) –  Oct 21 '13 at 02:49

2 Answers2

1

avoiding that lowest layers depend on highest layers

  • It's the contrary that should be avoided ;) High-level modules shouldn't depend on low-level details.

  • If lower level details are at the bottom, the Domain layer is misplaced on your schema. It should appear at the top.

    Think of it that way : the Domain layer contains your core business concepts and behavior. Are you ever going to swap out that Domain entirely while keeping the same Application layer ? Not likely to work/make any sense.

    In contrast, you could keep the Domain module and change the Application layer (think mobile app, web services that expose your domain, etc.) Same for the Infrastructure - you could change database, you could change your mail sender for another one. The Application is dependent on the Domain and tailored for it. The Infrastructure is dependent on the Domain as well. Not the other way around.

Which gives the typical following design :

  • Repository abstractions (interfaces) in the Domain layer. These expose contracts that manipulate domain objects (aggregate roots).

  • Repository implementations in the Infrastructure layer. The Infrastructure depends on the Domain, so no problem deriving your concrete repositories from the abstractions mentioned above.

  • (optional) Repository base classes in the Infrastructure layer. These are here to factor out elements that are common to all repositories, most often with regard to the underlying persistence technology (a database connection, an ORM change tracker, etc.)

  • Application layer classes only know about repository abstractions from the Domain layer, but at runtime are injected with their concrete implementations defined in the Infrastructure.

These thoughts lead me to the second question, is habitual that App Layer retrieve Domain Object from the repositories outside a Naked Object context? I feel that yes, and that the use of Data Transfer Objects is just needed when performance or another specific reason justified it, but if we design the Domain Layer interface in a way that knowledge leak is avoided (just exposing Domain Objects and Domain Services needed to the App Layer and not the internal ones), we will be safe. Has sense that line of thought?

That's correct (not to mention "internal" Domain objects and services have little reason to exist).

guillaume31
  • 12,725
  • 28
  • 43
  • Hi @guillaume31, thank for your reply. "It's the contrary that should be avoided ;) High-level modules shouldn't depend on low-level details." I don't agreed with you, neither Eric Evans when he said "Develop a design within each layer that is cohesive and that depends only on the layers below.". Pls note that I'm talking about layers not about module. About "If lower level details are at the bottom, the Domain layer is misplaced on your schema. It should appear at the top.", do you read the Evans book? in character four you can take a look at "Layered Architecture" and see that you are wrong. –  Oct 21 '13 at 12:59
  • "In contrast, you could keep the Domain module and change the Application layer..." I agreed, but I don't think that what I said refuse that, at contrary. "These expose contracts that manipulate domain objects (aggregate roots)." again, that is not totally true, as I said Evans talk about the convenience that App Layer talk to the infrastructure directly, bypassing the Domain Layer to retrieve some kind of Value objects... and again "The Infrastructure depends on the Domain" to which I don't agreed at all. "(optional) Repository base classes in the Infrastructure layer...." agreed. –  Oct 21 '13 at 13:46
  • "Application layer classes only know about repository abstractions from the Domain layer..." agreed. I really appreciate that you take time to reply but most of my questions are not answered and the way you see layer architecture is not that same way that community does (highest layers use services of lower layers and due to highest layer depend on lowest layer, while lower layers don't know about the existence neither depend on highest layers) –  Oct 21 '13 at 13:47
  • `the way you see layer architecture is not that same way that community does` - Fine, let's wait and see if "the community" has other answers that validate the way *you* see it, since that seems to be what your "questions" are all about. – guillaume31 Oct 21 '13 at 14:51
  • Thanks again for your reply @guillaume31 FYI, [this pic](http://www.ajlopez.com/images/articles/dddlayered.png) is how Eric Evans, the father of DDD, represent layers, so I don't feel that we must wait to see what the community have to said about, but read what it already said ;) What I'm interesting is in know community opinion about the two things I put in my question tittle, and my point of view about, not about layers disposition, cos is pretty much clear to me what community think about. Thanks again for you reply. –  Oct 21 '13 at 15:01
0

I am not a DDD expert, I am still learning it, but I try to answer your questions. This answer might not easy to understand, because I used different terms. I have 4 layers: presentation, application, domain and infrastructure. This is very different than your 3 layer architecture. Probably your application layer is my presentation layer and your domain layer is my application + domain layer, but I am not certain.

Can any body point me to some other reference that state something like that? or at least an explanation why?

I don't think that's true. Afaik. application services are in the application layer. In some figures this layer is part of the presentation while in others it is between the presentation and the domain. These services handle the commands and queries coming from the presentation. This is good because you can always write a different presentation for example a mobile client, and you can reuse the same application services meanwhile. Maintenance is easier too, because you don't have to find any code related to domain objects in the presentation. This kind of code will be only in the application and domain layers. Another cause that you can put your domain accessing code easily into transactions here.

These thoughts lead me to the second question, is habitual that App Layer retrieve Domain Object from the repositories outside a Naked Object context?

It is hard to answer this, since you miss the presentation layer here. Yes the domain objects are accessed in the application layer, but they cannot be accessed in the presentation layer. The application layer and the presentation layer send DTOs to each other instead of domain objects. So the UI will never use domain objects, just DTOs. So you domain objects will stay in their transaction and the DTOs can be used by the UI for example to display content. The DTOs can have different properties than the domain objects have and might have different validation as well.

Regarding to repositories. The interfaces of them are defined in the domain and they are implemented in the infrastructure. This is important because this way the infrastructure will depend on the domain, because the domain defines the interfaces it must implement. The same can happen with domain services too. So if your domain service has an infrastructure dependency, then you can define an interface in the domain, and implement it in the infrastructure. I am not sure about what the arrows mean in these figures. In order to make your application work you need to inject these implementations into the instances of the application and domain layer classes, but these classes depend only on the interfaces the domain layer defines. This is inversion of control in other terms. So the classes of the domain layer must not depend on any class outside of the domain layer. You can have for example ORM repositories in the infrastructure, so yes, there can be domain related repositories and infrastructure related repositories, but you should not confuse them.

I think I just wrote the same as guillaume31. :-) Probably the figure you linked: http://www.ajlopez.com/images/articles/dddlayered.png has some bugs. The classes in the domain must not depend on classes in the infrastructure. The most important rule here, that everything depends in the classes and interfaces of the domain and never the opposite... I read Vernon's book and I might read one of Evan's book, but I am not certain. I read too much in this topic and have not that much practical experience than the others. I am currently practicing DDD on a relative small project, but I really like it.

inf3rno
  • 20,735
  • 9
  • 97
  • 171