Correct Implementation Domain Driven Design - domain-driven-design

I have a important question for implementation about Domain Driven Design.
On the representation of layer architecture in evans's book, the Domain to references the layer Infrastructure this being the lowest layer, however I see in all implementations on the Internet the contrary, the infrastructure layer referencing the domain layer, maybe because of the implementation of the repository pattern using an ORM. What you guys think about this? Someone would have an example that implentasse exactly as Evans's book.

The examples that you see where interfaces lives in the domain (e.g. UserRepository) and their implementation lives in the infrastructure (e.g. HibernateUserRepository) are applying the Dependency Inversion Principle (DIP) to the traditional Layered Architecture.
In the traditional Layered Architecture, high level modules should depend on low-level modules. If we look at the standard layers order, we would have Domain -> Infrastructure.
Do we really want our domain to depend on infrastructure details? By applying the DIP principle, we inverse the dependency and make Infrastructure depend on the Domain layer, however it doesn't depend on concretions, but on abstractions.
Here's what the DIP principle states:
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.
Source: http://en.wikipedia.org/wiki/Dependency_inversion_principle

Are you sure you are looking at dependencies correctly? Repositories are not exactly infrastructure, they are located in between your domain and your data access layer.
As stated in Fowler's book, repository
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
If you are using a database, or, as you noted, an ORM, your repositories implementation will reference the ORM. Quite often, repository is implemented as a generic class, the only way it then "references" the domain as such is as it uses the base "entity" class for the generic constraint.
Very often data retrieval queries "by this" and "by that" are implemented in repository classes but this is not a very good practice. This work is for queries, or specifications, that a repository should be able to execute without knowing much of the details about them.

Related

domain driven design repository

I am learning DDD topic from scratch and on many DDD examples I see "repository interface" sitting in domain. What is real purpose of this repository actually/what does it do or solve exactly? Does this correspond or have some connection to persistence layer implementation?
Thank you.
What is real purpose of this repository actually/what does it do or solve exactly?
The reference for the REPOSITORY pattern in the context of domain-driven-design is chapter 6 of the "blue book" by Eric Evans. That is the chapter where he discusses lifecycle management patterns.
The repository is a facade, intended to support the illusion that DOMAIN ENTITIES (a chapter 5 pattern) are kept in an in-memory collection, somewhere. So when your process needs an entity, it asks the repository for it (usually offering an identifier as a hint).
It's a form of information hiding, in the Parnas 1971 sense; we can freely switch between transient collections stored in memory and durable collections stored on disk, or in the RDBMS, or in the key/value store. Only the implementation(s) of the repository need to worry about the specifics of the plumbing.
The motivation was largely to separate developer focus; the separation of ideas permits developers working on the "business rules" to concentrate on the domain, without being distracted by the concerns of storage and retrieval.
The Repository interface sits in the Domain layer and the Repository itself is implemented in the Infrastructure layer. Defining the Repository interface in the Domain layer allows to easily switch between Infrastructure implementations, knowing that all follow the same interface.
Ultimately, the Application layer will call a Repository implementation from the infrastructure layer. To go further, you can even define an Application interface based on the Repository interface, and then an Application implementation where you inject the selected Repository implementation from the Infrastructure layer.

DDD why should domain model define interfaces for infrastructure

While studying DDD I'm wondering why the Domain model need to define interfaces for the Infrastructure layer.
From my reads I got that a high level (domain model, application service, domain service) defines interfaces that need to be implemented by a lower layer (infrastructure). Simple.
From this idea I think it makes sense that an application level (in a high level) defines interfaces for a lower one (infrastructure) because the application level will use infrastructure components (A repository is a usual client of the applicaiton layer) but doesn't want to be tied to any special implementation.
However, this is confusing when I see in some books a domain level defining infrastructure interfaces because a domain model will not use ever a repository because we want our domain model "pure".
Am I missing something?
While studying DDD I'm wondering why the Domain model need to define interfaces for the Infrastructure layer.
It doesn't really -- that's part of the point.
The domain model defines the interfaces / contracts that it needs to do work, with the promise of happily working with any implementation that conforms to the contract.
So you can choose to implement the interface in your application component, or in the infrastructure component, or where ever makes sense.
Note the shift in language from "layer" to "component". Layers may be too simplistic to work -- see Udi Dahan 2007.
I came across the same question myself. From my understanding, the reason behind this is that you want the application to only consume objects/interfaces defined in the Domain Model. It also helps to keep one repository per aggregate since they sit next to each other in the same layer.
The fact that the Application layer has a reference to the Infrastructure layer is only for the purpose of dependency injection. Your Application layer services should call these interfaces exposed in the Domain layer, get Domain Objects (POCOs), do things and possibly call interfaces again; for example to commit a transaction. This is why for example the Unit of Work pattern exposes its action through a Domain Layer interface.

Eric Evans book - Cargo shipping example - Repository purpose

I'm reading Evans's book Domain Driven Design, and I'm a bit stuck on understanding the example about Cargo Shipping and repositories, in chapter 7.
In "An Alternative Design of the Cargo AGGREGATE" he replaced Delivery History's collection with a query in order to reduce circular complexity and prevent transactions from locking.
Now I'm puzzled, wasn't the whole purpose of introducing Repositories separation of infrastructure layer from domain? If Deivery History is going to make queries, than it eather needs a reference to an appropriate repository or it itself has to implement some of the repository responsibilities? How does separation of entities and repositories work?
Implementing Domain Driven Design By Vernon explores some of the practical considerations with this in more depth. In particular, in the hexagonal architecture, you could actually treat the repository implementations as internal adapters. Then the repository is merely an interface to the underlying data store, and as such is fully part of the domain itself as an abstraction. This means any entity could reference the repository abstraction, and with the implementations outside the core domain, the layered architecture is preserved.
Of course there are many ways to implement this, and I think in some ways the original Evans book is not as prescriptive about the specifics, and rather focuses on the key patterns rather than all the implementation details.

DDD vs N-Tier (3-Tier) Architecture

I have been practicing DDD for a while now with the 4 distinct layers: Domain, Presentation, Application, and Infrastructure. Recently, I introduced a friend of mine to the DDD concept and he thought it introduced an unnecessary layer of complexity (specifically targeting interfaces and IoC). Usually, its at this point, I explain the benefits of DDD-- especially, its modularity. All the heavy lifting and under the hood stuff is in the Infrastructure and if I wanted to completely change the underlying data-access method, I could do so with only having to touch the Infrastructure layer repository.
My friend's argument is that he could build a three tiered application in the same way:
Business
Data
Presentation
He would create business models (like domain models) and have the repositories in the Data layer return those Business models. Then he would call the business layer which called the data layer. I told him the problem with that approach is that it is not testable. Sure, you can write integration tests, but you can't write true unit tests. Can you see any other problems with his proposed 3-tiered approach (I know there is, because why would DDD exist otherwise?).
EDIT: He is not using IoC. Each layer in his example is dependent on one another.
I think you're comparing apples and oranges. Nothing about N-Tier prohibits it from utilizing interfaces & DI in order to be easily unit-tested. Likewise, DDD can be done with static classes and hard dependencies.
Furthermore, if he's implementing business objects and using Repositories, it sounds like he IS doing DDD, and you are quibbling over little more than semantics.
Are you sure the issue isn't simply over using DI/IoC or not?
I think you are mixing a few methodologies up. DDD is Domain-Driven Developement and is about making the business domain a part of your code. What you are describing sounds more like the Onion Architecture (link) versus a 'normal' 3-layered approach. There is nothing wrong with using a 3-layered architecture with DDD. DDD depends on TDD (TestDriven Developement). Interfaces help with TDD as it is easier to test each class in isolation. If you use Dependency Injection (and IoC) it is further mitigated.
The Onion Architecture is about making the Domain (a.k.a. business rules) independent of everything else - ie. it's the core of the application with everything depending on the business objects and rules while things related to infrastructure, UI and so on are in the outer layers. The idea is that the closer to the 'shell of the onion' a module is - the easier it is to exchange for a new implementation.
Hope this clears it a bit up - now with a minor edit!
Read "Fundamentals of Software Architecture: An Engineering Approach", Chapter 8, Page 100 to 107.
The top-level partitioning is of particular interest to architects because it defines the fundamental architecture style and way of partitioning code. It is one of the first decisions an architect must make. These two styles (DDD & Layered) represent different ways to top-level partition the architecture. So, you are not comparing apples and oranges here.
Architects using technical partitioning organize the components of the system by technical capabilities: presentation, business rules, persistence, and so on.
Domain partitioning, inspired by the Eric Evan book Domain-Driven Design, which is a modeling technique for decomposing complex software systems. In DDD, the architect identifies domains or workflows independent and decoupled from each other.
The domain partitioning (DDD) may use a persistence library and have a separate layer for business rules, but the top-level partitioning revolves around domains. Each component in the domain partitioning may have subcomponents, including layers, but the top-level partitioning focuses on domains, which better reflects the kinds of changes that most often occur on projects.
So you can implement layers on each component of DDD (your friend is doing the opposite, which is interesting and we might try that out as well).
However, please note that ("Fundamentals of Software Architecture: An Engineering Approach", Page 135)
The layered architecture is a technically partitioned architecture (as
opposed to a domain-partitioned architecture). Groups of components,
rather than being grouped by domain (such as customer), are grouped by
their technical role in the architecture (such as presentation or
business). As a result, any particular business domain is spread
throughout all of the layers of the architecture. For example, the
domain of “customer” is contained in the presentation layer, business
layer, rules layer, services layer, and database layer, making it
difficult to apply changes to that domain. As a result, a
domain-driven design approach does not work as well with the layered
architecture style.
Everything in architecture is a trade-off, which is why the famous answer to every architecture question in the universe is “it depends.” Being said that, the disadvantage with your friend's approach is, it has higher coupling at the data level. Moreover, it will creates difficulties in untangling the data relationships if the architects later want to migrate this architecture to a distributed system (ex. microservices).
N Tier or in this case 3-tier architecture is working great with unit tests .
All you have to do is IoC (inversion of control) using dependency injection and repository pattern .
The business layer can validate , and prepare the returned data for the presentation \ web api layer by returning the exact data which is required .
You can then use mock in you unit tests all the way through the layers.
All your business logic and needs can be on bl layer . And Dal layer will contain repositories injected from higher level.

Which layer should Repositories go in?

Which layer should the repository classes go in? Domain or Infrastructure?
The repository interfaces are part of the domain. The actual implementation of the interfaces should be part of the infrastructure.
Repository implementation classes, together with separate interfaces (if they exist) should go into the domain layer.
The reason is given by the fundamental rule to be followed in a layered architecture: a lower layer must not depend on a higher layer.
If we accept this rule (otherwise it's not a layered architecture), then putting repository implementations into the infrastructure layer would make it dependant on the domain layer, therefore violating the fundamental rule of layering.
For example, when we create a new domain entity, we put it in the domain layer; and since a repository (both its interface and its implementation) must inevitably depend on the domain entity, it means the repository must also go into the domain layer. Otherwise, we would be changing the infrastructure layer whenever a domain entity was added/removed/modified in the domain layer.
Other concerns, such as keeping the domain layer "clean" and independent of persistence details, can and should be achieved by using the appropriate infrastructure services from the implementations inside the domain layer. For example, in Java we can use JPA to implement repositories with very little code, and no SQL/JDBC or database-specific code (whether it's really a good idea to implement repositories with JPA is another discussion; in any case, JPA entities will make use of JPA annotations anyway).
References: Wikipedia,
MSDN
Repository classes implementations should be situated in the Infrastructural Layer. Repository interfaces should be in the Service Layer.
Domain Layer should know nothing about the repositories. Strategic patterns of DDD state that Domain Layer should always be in sync with conceptual model. That means that Domain Layer should translate well known domain processes to code and vice versa. And domain process is what your domain experts should know well. And domain experts know nothing about repositories.
Another way to think about it. Let us suppose we put repositories or the interfaces of repositories into a Domain Layer. I.e. now we have the repository concept in Domain Layer code. Also, the Domain Layer should be in sync with the conceptual model of domain. So, let us ask ourselves what is the representation of repository in the conceptual model. The correct answer is that there is no repository in the conceptual model. Hence, repository can not be in Domain Layer.
All said, I still come across projects which have repositories in the Domain Layer and engineers on the projects still call it a DDD practice. I assume the problem here is that people do not pay a lot of attention to strategic patterns which lie at the heart of DDD, but just play around with the tactical patterns which may simplify coding efforts a bit.
I guess that depends how You are going to rely on them.
Question is - are You going to allow Yourself to use repositories from inside of domain?
If so - then You are forced to put them in.
I myself like to put them outside of domain. So - typical life cycle of something looks like this =>
UI => Controller => retrieve aggregate root from repo => call logic through aggregate root => if new aggregate root created, add it to repo.
Sometimes controller calls application service that does some additional stuff besides just retrieving root and calling function on it. But idea is same - domain knows nothing about persistence.
While (as I see it) there's nothing wrong with putting repos in domain (or at least abstractions of them), it makes Your domain more aware of persistence. Sometimes that can solve problems, but generally - that will definitely make Your domain more complex.
Use what seems more natural for You and be ready to switch Your ways any time.

Resources