I'm modeling my first DDD application and I caught stuck with this doubt...
In my application and infrastucture layers I have some details that need to be persisted, but, since these are not domain specific, I don't like to name it repositories. Someone can help me figure out how to name it?
Thanks.
DDD and the Repository pattern (RP) are different things, it just happens that DDD makes use of RP. This means that you can wrap everything related to persistence in repositories, they just won't be Domain Repositories. Probably in your case you'd have PaymentGatewaysRepository or smth like that.
Point is, if you wrap persistence access details into a class so that the rest of the app doesn't care about storage, you're using the repository pattern no matter how you'll name that class.
You should elaborate some more... Why isn't it modeled? Is it only configuration settings, things outside of the scope of the model? Like logs, etc? Some names come to mind: Serialization, configuration, settings, etc.
Considering your comment, configuration settings are really orthogonal to a Domain Model, but payment gateway settings may or may not be outside of the model. Id depends on the kind of application you are writing. I believe that if you are writing a payment processor, then it is a bona fide "member of your" domain model :-) You can also model generic configurations in the model... imagine that your users will have their own overriden settings.. The config "model" could weakly reference the domain model...
You can also model these specifics in another domain entirely... a reusable domain model with its own persistence, and which could be used in different domains as an add-on...
Related
I am new to DDD and this is the first project for me to apply DDD and clean architecture,
I have implemented some code in the domain layer and in the application layer but currently, I have a confusion
now I have an API which is placeOrder
and to place the order I need to grab data from other microservices, so I need to grab production details from product service and address details from user profile microservice
my question is, should these data are pulled into the domain layer or in the application layer?
is it possible to implement a domain service that has some interfaces that represent the product service API and use that interface in the domain layer and it will be injected later using dependency injection or should I implement the calling of this remote API in the application layer?
please note that, calling product service and address service are prior steps to create the order
Design is what we do when we want to get more of what we want than we would get by just doing it. -- Ruth Malan
should these data are pulled into the domain layer or in the application layer?
Eric Evans, introducing chapter four of the original DDD book, wrote
We need to decouple the domain objects from other functions of the system, so we can avoid confusing the domain concepts with other concepts related only to software technology or losing sight of the domain altogether in the mass of the system.
The domain model doesn't particularly care whether the information it is processing comes from a remote microservice or a cache. It certainly isn't interested in things like network failures and re-try strategies.
Thus, in an idealized system, the domain model would only be concerned with the manipulation of business information, and all of the "plumbing" would be somewhere else.
Sometimes, we run into business processes where (a) some information is relatively "expensive" to acquire and (b) you don't know whether or not you need that information until you start processing the work.
In that situation, you need to start making some choices: does the domain code return a signal to the application code to announce that it needs more information, or do we instead pass to the domain code the capability to get the information for itself?
Offering the retrieve capability to the domain code, behind the facade of a "domain service" is a common implementation of the latter approach. It works fine when your failure modes are trivial (queries never fail; or abort-on-failure is an acceptable policy).
You are certainly going to be passing an implementation of that domain service to the domain model; whether you pass it as a method argument or as a constructor argument really depends on the overall design. I wouldn't normally expect to see a domain entity with a domain service property, but a "use case" that manipulates entities might have one.
That all said, do keep in mind that nobody is handing out prizes for separating domain and application code in your designs. "Doing it according to the book" is only a win if that helps us to be more cost effective in delivering solutions with business value.
I am incredibly new to Domain Models and I am trying to build up my understanding. I have created this domain model around a scenario which I will provide. I feel this model is simple and as a result, feels incorrect and might be missing elements I might not have thought of although, I cannot think of what else might need to be included in a domain model given the scenario. The idea is to demonstrate the relationship between real world class entities which I feel I have managed to achieve.
Scenario: Management Application that allows you to create users, projects, companies and issue tickets. The projects are assigned to companies, the users are assigned to projects and the issue tickets are assigned to the users. Tickets have a status which can be changed.
Changes
Implementing proposed changes. I think this is a better way to represent the idea based on the feedback returned, especially in regards to the use of composition. I have also updated the multiplicities to better represent the scenario.
Further changes
The diagram should stay as simple as possible, but not more.
In this specific case:
The two specializations of User might be too complex for the need: a User stays a User, isn’t it? If you really need to take into account differences between categories of users, and especially if the category changes over time, you'd better consider (object) composition over inheritance (or better worded for UML: prefer association over inheritance).
The associations might be too simple or incomplete. For example, before an Issue ticket gets assigned to a User, isn’t it also associated to a Project or a Company? It is not clear either if User is also associated to Company (e.g. multi-tenant cloud scenario) or if there is no such association (e.g service provider scenario, where the company is in fact a customer company).
Some associations may hide association classes, e.g. do you expect to monitor how many time a user worked on a ticket?
It entirely depends on the purpose of your model.
Some models might be created to stimulate discussion and further discovery. Some might be required for the senior stakeholders to approve. Some might be for developers to work from. Others might be for marketing material.
Your model is ok for stimulating discussion and further discovery.
In DDD, I've seen the following code many times where an entity is passed as parameter to the save method of a repository.
class MysqlUserRepository
{
public function save(User $user) {}
}
As far as I know, infrastructure shouldn't know anything about domain. If this is correct, what am I missing here?
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.
See: https://martinfowler.com/eaaCatalog/repository.html
Repository is a mediator that has to "translate" from persistence to domain and vice versa. Persistence infrastructure get/gives "raw" data so there has to be something that allows to glue these two worlds in the most possible decoupled way. That means Repository has to know both worlds.
As ar as I know, infrastructure shouldn’t know anything about the domain
That's a valid point, which I believe can be concluded from Eric Evans his book “Domain-Driven Design”. Note however, that Eric Evans leaves us somewhat in a paradoxal state.
In his book he talks about a layered architecture, from top to bottom:
“User Interface” —> “Application” —> “Domain” —> “Infrastructure”.
With it, he states:
The essential principle is that any element of a layer depends only on other elements in the same layer or on elements of the layers “beneath” it.
From this we can conclude that the infrastucture layer (being beneath the domain layer) should have no knowledge about the domain layer. However, Evans also talks about the domain layer being the layer that defines the repository. In other words, we've reached an impossible state.
Since then, more has been written about Domain-Driven Design and I believe it was Vaughn Vernon’s book “Implementing Domain-Driven Design” that comes with a solution.
Instead of using a layered architecture, we could use Hexagonal Architecture defined by Alistair Cockburn. The mind-shift with Hexagonal Architecture is that the application is no longer an asymmetric, top-down, layered architecture. Instead it places the domain layer at the center. Everything else, including the infrastructure layer is placed outside this center (or hexagon). Communication is possible using ports defined by the domain "layer". The Repository can be seen as an example of such a port.
So the Domain layer can expose a port, in your case UserRepositoryInterface. Following Hexagonal Architecture, the infrastructure layer is allowed to communicate with the domain "layer". As such, it can implement the interface with MysqlUserRepository.
... infrastructure shouldn't know anything about domain. If this is correct ...
This isn't correct. In DDD, infraestructure layer depends on domain layer, so it knows anything the domain wants to show. There's no rule in DDD about how many things the domain should show. It's up to you: you can show the whole entity, you can show a DTO, a DPO, ...
On the other hand, domain doesn't know anything about infraestructure (this is correct).
I'm looking at developing a system (primarily web based) that has a clearly defined domain.
Parts of the domain include entities like Diary, Booking, Customer, etc.
However I created another entity called User whose intention is for authentication and authorization only (it seemed wrong to contaminate the Customer entity with data specific to authentication). I figure this isn't part of the domain of "making bookings", but specifically this should belong to the application layer (I'm trialling a hexagonal architecture).
I'm accessing my repositories using interfaces in my domain model and wiring them up to my persistence layer using IoC.
My questions are this:
Should I put the authentication/authorization code in the application
and keep it out of the domain?
If I do keep it out of the domain, should I put the interface for the
UserRepository in the application layer also (I think this would
make sense)?
If I do keep it out of the domain, I will end up with entities also in the application layer called User etc. This seems wrong.
What are people's thoughts?
[EDIT]
I've gone for a solution that takes a bit from both answers, so thanks for answering and I've +1'd you both.
What I've done is put the authentication/authorisation code in a subdomain (secondary adapter), in a separate project, and because it requires access to it's own persistence (a few collections in a separate RavenDB database), I'm including these straight into the separate project keeping them separate from the main persistence layer.
Should I put the authentication/authorization code in the application
and keep it out of the domain?
No, you should keep authentication/authorization code out of the core domain. It belongs to a generic subdomain.
If I do keep it out of the domain, should I put the interface for the
UserRepository in the application layer also (I think this would make
sense)?
You could keep UserRepository in the domain layer, but you'd better keep the "access and identify" subdomain and the "making bookings" core domain separated with each other. You could use different packages or namespace.
The next challenge is how to integrate these two domains. In my humble opinion, you may:
Expose a DomainService from "access and identify" subdomain to the application layer for making authentication/authorization decisions.
Sometimes we have to find out who made Diaries and Bookings, in this case, use the identifier of the User is enough. Other information such as "favorite tags" or something like that is usually not needed in "making booking" core domain.
Authentication is a generic domain, not a part of your domain. So, yes, keep it in some component in application layer.
Not all parts of your system should follow DDD patterns. You can use UserRepository if you see a benefit for this but I would use just some already available component/popular library of your environment like MembershipProvider in ASP.NET world.
I'm working on my first "real" DDD application.
Currently my client does not have access to my domain layer and requests changes to the domain by issuing commands.
I then have a separate (flattened) read model for displaying information (like simple CQRS).
I'm now working on configuration, or specifically, settings that the user configures. Using a blog application as an example, the settings might be the blog title or logo.
I've developed a generic configuration builder that builds a strongly typed configuration object (e.g. BlogSettings) based on a simple key value pair collection. I'm stuck on whether these configuration objects are part of my domain. I need access to them from the client and server.
I'm considering creating a "Shared" library that contains these configuration objects. Is this the correct approach?
Finally where should the code to save such configuration settings live? An easy solution would be to put this code in my Domain.Persistence project, but then, if they are not part of the domain, should they really be there?
Thanks,
Ben
User configurable settings belong to domain if they are strongly typed and modeled based on ubiquitous language, i.e. 'BlogSettings'. The only difference between settings and other domain objects is that conceptually settings are 'domain singletons'. They don't have a life cycle like other Entities and you can only have one instance.
Generic configuration builder belongs to Persistence just like the code that is responsible for saving and reading settings.
Having found this question, I feel obliged to suggest an answer because I don't like the accepted one.
First off I don't see why this has to be a singleton.
Secondly, there is something about settings that is very important: they are usually hierarchical, and they almost always have to have the concept of defaults. Sometimes those defaults are at the item level. Other times you might prefer to replicate a whole set of defaults. Also, consider the fact that settings can use the concept of inheritance: maybe an agency has a setting, but it permits agents the ability to do their own.