Eric Evans book - Cargo shipping example - Repository purpose - domain-driven-design

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.

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 repository and factory

In my application a few layers.
In this topic will focus on Domain and Infrastructure layers.
I have repository interface ClientRepositoryInterface in Domain layer.
And I have implementation of this interface ClientRepositoryImpl in Infrastructure layer.
But to reconstitute the object in the middle of the cycle of its existence I need factory(ReconstitutionClientFactory).
Call the factory will be in the repository.
The book by Eric Evans is described as a normal practice.
But where this factory(ReconstitutionClientFactory) should be located? In Domain or in Infrastructure layer?
I think in Domain...
BUT! But then the lower layer will directly call a higher layer!
This is wrong, but how to do right?
Factory & Repository Concepts
To answer your question, I think it's important to focus on responsibilities of the concepts defined by DDD.
In the blue book, there is a section that deals with the problem that you describe:
A FACTORY handles the beginning of an object’s life; a REPOSITORY helps manage the middle and the end.
and specifically for your question:
Because the REPOSITORY is, in this case, creating objects based on data, many people consider the REPOSITORY to be a FACTORY—indeed it is, from a technical point of view.
(both quotes from Evans, chapter 6, section "The relationship with factories")
To keep the concepts pure, it is important that the interface of your factories and repositories are clean. So don't allow creating new business objects through the repository interface, and don't allow querying existing ones through the factory interface.
Keeping the interfaces clean does however not mean that you should not use a factory from the repository implementation, because, after all, the repository creates an instance at some point, and if that instance creation is complex, a factory is the appropriate solution.
To quote Evans again:
Whenever there is exposed complexity in reconstituting an object from another medium, the FACTORY is a good option.
Note, however, that the repository will most likely call a different method on the factory than the clients that really want to create a new domain object (as opposed to reconstitution).
There is even an example in Evans' book that illustrates approach:
Answer to your question
Now that it is clear that this is allowed, lets focus on your question of where to put the factory:
The DDD factory interface belongs in the domain, because your domain logic uses this to create domain objects.
The DDD reconstitution factory interface does not belong in the domain, since this is only relevant for your repository. It does not exist in the real world of your domain.
Now if you're using an architecture that prohibits dependencies from the domain to the infrastructure (which you probably should when applying DDD), it's clear that the factory implementation belongs in the infrastructure. Note that it does not matter whether you call your layers layers, rings, realms or whatever, the dependencies are the important part.
First of all, the layers approach is kinda obsolete. When talking layers think 'context', who's on top of who isn't important.
The repository is in charge of restoring an object. A factory just creates a new object. Note the different semantics. The repository knows how saving/restoring to/from persistence is done and that depends on the storage and the method of access.
So, everything is done inside the repository i.e in the Infrastructure. If you serialize things, then you need just to deserialize back (this is how a document db does things anyway). If you're using an ORM or store things in tables then you'll do all the query required to get the data and repopulate the object. An ORM is the easiest way since it can use reflection to populate private properties. In this case the ORM itself is the factory.
One more thing, restoring, while technically can be done by a domain factory, it isn't the factory's purpose to do that because it breaks the layer boundaries. We want to keep everything persistence related in the Infrastructure.

Correct Implementation 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.

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.

Questions regarding Domain driven Design

After reading Eric Evans' Domain driven Design I have a few questions. I searched but no where i could able to find satisfying answers. Please let me know if anyone of you have clear understanding below questions.
My concerns are
Repository is for getting already existing aggregates from DB,Web service .
If yes, Can Repository also have transaction calls on this entity (i.e Transfer amount,send account details ...etc)
Can Entity have Methods which have business logic in which it calls infrastructure Layer services for sending emails .. logs etc (Entity methods calling IS services direclty).
Repository implementation and Factory classes will reside in Infrastrucure Layer. is that correct statement ?
Can UI layer (controller) call Repositry methods directly ? or should we call these from Application layer ?
There are still lot many confusion in my mind ... please guide me ...
Books i am using Eric Evan's domain driven desing ......
.NET Domain-Driven Design with C#
There is a lot of debate about whether Repositories should be read-only or allow transactions. DDD doesn't dictate any of these views. You can do both. Proponents of read-only Repositories prefer Unit of Work for all CUD operations.
Most people (self included) consider it good practice that Entities are Persistent-Ignorant. Extending that principle a bit would indicate that they should be self-contained and free of all infrastructure layer services - even in abstract form. So I would say that calls to infrastructure services belong in Service classes that operate on Entities.
It sounds correct that Repository implementations and Factories (if any) should reside in the infrastructure layer. Their interfaces, however, must reside in the Domain Layer so that the domain services can interact with them without having dependencies on the infrastructure layer.
DDD doesn't really dictate whether you can skip layers or not. Late in the book, Evans talks a bit about layering and calls it Relaxed Layering when you allow this, so I guess he just sees it as one option among several. Personally I'd prefer to prevent layer skipping, because it makes it easier to inject some behavior at a future time if calls already go through the correct layers.
Personally, in my latest DDD-project, I use a Unit Of Work that holds an NHibernate session. The UoW is ctor injected in the repositories, giving them the single responsible of Add, Remove and Find.
Evans has stated that one piece of the puzzle that's missing in the DDD book is «Domain Events». Using something like Udi Dahan's DomainEvents will give you a totally decoupled architecture (the domain object simply raises an event). Personally, I use a modified version of Domain Events and StructureMap for the wiring. It works great for my needs.
I recommend, based on other recommendations, that the Repository interfaces be a part of the model, and their implementations be a part of the infrastructure.
Yes! I've personally worked on three DDD web projects where services and repositories were injected to the presenters/controllers (ASP.NET/ASP.NET MVC) and it made a lot of sense in our context.
The repository should only be for locating and saving entities, there should not be any business logic in that layer. For example:
repository.TransferAmount(amount, toAccount); // this is bad
Entities can do things like send emails as long as they depend on abstractions defined in your domain. The implementation should be in your infrastructure layer.
Yes, you put your repository implementation in your infrastructure layer.
Can UI layer (controller) call Repositry methods directly ? or should we call these from Application layer ?
Yes, I try to follow this pattern for the most part:
[UnitOfWork]
public ActionResult MyControllerAction(int id)
{
var entity = repository.FindById(id);
entity.DoSomeBusinessLogic();
repository.Update(entity);
}

Resources