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).
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.
Several sources claim that process managers do not contain any business logic. A Microsoft article for example says this:
You should not use a process manager to implement any business logic in your domain. Business logic belongs in the aggregate types.
Further up they also say this (emphasis mine):
It's important to note that the process manager does not perform any business logic. It only routes messages, and in some cases translates between message types.
However, I fail to see why translations between messages (e.g. from a domain event to a command) are not part of the business logic. You require a domain expert in order to know what the correct order of steps and the translations between them are. In some cases you also need to persist state in-between steps, and you maybe even select next steps based on some (business) condition. So not everything is a static list of given steps (although that alone I’d call business logic too).
In many ways a process manager (or saga for that matter) is just another aggregate type that persists state and may have some business invariants, in my opinion.
Assuming that we implement DDD with a hexagonal architecture, I‘d place the process manager in the application layer (not adapter!!) such that it can react to messages or be triggered by a timer. It would load a corresponding process manager aggregate via a repository and call methods on it that either set its (business) state or ask it for the next command to send (where the actual sending is done by the application layer of course). This aggregate lives in the domain layer because it does business logic.
I really don‘t understand why people make a distinction between business rules and workflow rules. If you delete everything except the domain layer, you should be able to reconstruct a working application without the need to consult a domain expert again.
I‘d be happy to get some further insight I might be missing from you guys.
A fair portion of the confusion here is a consequence of semantic diffusion.
The spelling "process manager" comes from Enterprise Integration Patterns (Hohpe and Woolf, 2003). There, it is a messaging pattern; more precisely, it is one possible specialization of a message router. The motivation for a message router is a decoupling of the sender and receiver.
If new message types are defined, new processing components are added, or routing rules change, we need to change only the Message Router logic, while all other components remain unaffected.
Process manager, in this context, refers to a specialization of message router that sits in the middle of a hub and spoke design, maintaining the state of the processing sequence and "determining the next processing step based on intermediate results".
The "process definition" is, of course, something that the business cares about -- we're passing these messages around to coordinate activities in different parts of the enterprise, after all.
And yes... this thing that maintains the "state of the processing sequence", sounds a lot like an example of a "domain entity", this is true.
BUT: it is an entity of the message routing domain; which is to say that it is bookkeeping to ensure that messages go to the right place rather than bookkeeping of business information (ie: the routing of shipping containers).
Expressed in the language of hexagonal architecture, what a process manager is doing is keeping track of messages sent to other hexagons (and, of course, the messages that they send back).
Domain logic is not only to be found in aggregates and domain services. Other places are:
Appropriately handling domain events. Domain events can be translated into one or multiple commands to aggregates; they can trigger those commands based on some condition/policy on the event itself and/or the state of other aggregates; they can inform an ongoing business process to proceed with its next step(s), and so forth. All of these things are part of domain logic.
A business process is a (potentially distributed) state machine that may involve various actors/users/systems. The allowed states and transitions between them are all a core part of the domain logic.
A saga is an eventually consistent transaction spanning multiple local or foreign aggregates that completes either successfully or compensates already executed steps in a best-effort manner. The steps that make up a saga can only be known to domain experts and thus are part of the domain logic.
The reasons why these three things are – in my opinion – mistaken as an application-layer-only concern are the following:
In order to handle a domain event, we must load and later save the affected aggregates. Because of this, the handler must also be part of the application layer. But crucially, not only. If we respect the idea behind a hexagonal architecture, then for each domain event handler residing in the application layer, there must be a corresponding one located in the domain layer. Even for the most trivial case where one domain event translates to exactly one command method invocation on some aggregate. This is probably omitted in many examples because it initially adds little value. But just imagine that later on, the translation will be based on some further business condition. Will we also just place that in the application layer handler? Remember: All of our domain logic should be in the domain layer.
A side note: Even if we respect this separation of concerns, we still have the choice of letting the domain event be handled by an aggregate itself or let it be translated into an aggregate command by a thin domain service. This choice however is based on an entirely different concern: Whether or not we want to couple aggregates more tightly. There is no right or wrong answer here. Some things just naturally are coupled more tightly while others might benefit from some extra indirection for increased flexibility.
In order to correctly implement a business process or saga, we have to take care of various application-specific concerns like message de-duplication, idempotency, retries, timeouts, logging etc. Although one might argue that the domain logic itself should be responsible for dealing with at least some of these aspects first-hand (see Vaughn Vernons excellent talk about modelling uncertainty). Remember, however, that the essence of the sequence of (allowed) steps/actions is entirely based on domain logic.
Finally, a word about coupling. In my view, there is a tendency in the community that coupling is a bad thing per-se and thus must be avoided/mitigated by all means. This might lead to solutions like placing event-command translations (remember: domain logic!) out in the adapter layer of a hexagonal/onion/clean architecture. This layers responsibility is to adapt something to something else with the same semantics/function, but with slightly different form (think power adapters). It is not the place to host any type of domain logic even if it is dead simple. Businesses have dependencies and coupling all over the place. The art is to embrace it where it actually is, and avoid it otherwise. There is a reason why we have partnership or customer/supplier relationships in DDD. And if we care about domain logic isolation, those dependencies are reflected right where they belong: In the domain layer.
A side note: An anti-corruption layer (DDD) is a valid example of an adapter. For example, it may take a bunch of remote domain events and transform/combine them in any way necessary to suit the local model. They still remain events that happened in the past, and don't just magically become commands. The transformation only changes form, not function. And it doesn't eliminate the inevitable coupling from a domain perspective. It just rephrases the same thing in a slightly different language.
a) Do Core Domain and Generic Subdomain ( GS ) in most cases contain different parts of the same domain model or does each GS define its own domain model, which is usually different from the model used in Core Domain?
b) If the former, then I assume the reason for both using the same model is because the primary purpose of GS is to "serve" a Core Domain, and GS can "serve" best if there's no need for a translation layer between the Core Domain and GS ( if each used its own model, then we'd also need a translation layer between the GS and Core Domain )?
thanks
Core Domains, Supporting Subdomains and Generic Subdomains evolve around the concept of the Bounded Context in DDD.
To answer your question, the Core Domain is the domain which makes your business unique and gives you an advantage over your competitors - you will put most efforts (developers/monry) into improving it. A Generic Subdomain handles a topic that is still important but there is a chance you'll find an existing solution (either as a concept or reusable code) that handles the tasks good enough.
The Generic Subdomain would have a different model because it tackles a different domain.
A Generic Subdomain may describe anything from date/time(zone) handling see (2, Ch. 15), persistence, the user-interface toolkit up to a mail server or a complete inventory management system (1, Ch. 2). On the other hand, the inventory management logic is the Core Domain of the inventory management system's vendor.
You can find in-depth information in the book Implementing Domain-Driven Design and of course in the original book introducing Domain-Driven Design by Eric Evans.
Update: (see comment)
In my opinion, the most important aspect in Core Domains using any kind of Subdomain is not to overthink this topic on an abstract level. You'll probably agree that the biggest challenge in Domain-Driven Design is to find good examples that, by plan or accidentally, match the patterns/strategies from the Strategic Design section of the Domain-Driven Design book.
Now, from my understanding, the need for a translation layer between Core Domain and Generic Subdomains arises simply from necessity. In Chapter 15, Distillation of Domain-Driven Design four options on how to develop Generic Subdomains are discussed with their corresponding pros and cons:
An Off-the-Shelf Solution
A Published Design or Model
An Outsourced Implementation
An In-House Implementation
I won't repeat the discussion because this would just include quoting from the excellent book. You'll probably agree that a custom tailored and well-designed in-house solution, that is only used for this project, does not need a translation layer. On the other hand, a commercial or open-source Off-the-Shelf Solution is more likely to require an abstraction because you have little control on how the product evolves, if it has an appropriate Intention-Revealing Interface and so on.
There are two other aspects that are related but should not be mixed up with Subdomains:
Communication between Bounded Contexts
Cohesive Mechanisms
Bounded Contexts need some kind of translation by sheer definition. For each Bounded Context, there is a Model in Context. A Context Map documents the relationships and interactions of Bounded Contexts with Translation Map. The different ways of relating models of BoundedContexts are discussed in Chapter 14, Mainting Model Integrity (Anti-Corruption Layer, Open-Host Service and others).
Cohesive Mechanisms (see Chapter 15 of Domain-Driven Design), on the other hand, are similar to Generic Subdomains as both are introduced to relieve the Core Domain from unnecessary clutter. Eric Evans describes Cohesive Mechanisms as a lightweight framework but admits that in practice the distinction between Cohesive Mechanisms and Generic Subdomains is mostly not pure.
I'd like to say that I had to read those sections again as I do not deal with this on a daily basis so please be forgiving. Additionally, I am not in the inner circle of the DDD community and thus I am not aware if these issues are evaluated differently today. They still seem very useful to me and I have not encountered a better set of tools in this area so I assume they are still valid.
I understand the urge to understand these concepts but a real understanding can only be achieved by looking at concrete examples. Some are mentioned in the books. None of them are claimed perfect. The understanding and assessment of these complex problems, large or small, changes over time and this the soul of DDD in my opinion.
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...
Can somebody please explain (in succinct terms) what exactly is domain driven design? I see the term quite a lot but really don't understand what it is or what it looks like. How does it differ from non-domain driven design?
Also, can somebody explain what a Domain Object is? How does domain differ from normal objects?
EDIT:
As this seem to be a top result on Google and my answer below is not, please refer to this much better answer:
https://stackoverflow.com/a/1222488/1240557
OLD ANSWER (not so complete :))
In order to create good software, you have to know what that software
is all about. You cannot create a banking software system unless you
have a good understanding of what banking is all about, one must
understand the domain of banking.
From: Domain Driven Design by Eric Evans.
This book does a pretty good job of describing DDD.
Register to download a summary of the book.
Domain Driven Design is a methodology and process prescription for the development of complex systems whose focus is mapping activities, tasks, events, and data within a problem domain into the technology artifacts of a solution domain.
The emphasis of Domain Driven Design is to understand the problem domain in order to create an abstract model of the problem domain which can then be implemented in a particular set of technologies. Domain Driven Design as a methodology provides guidelines for how this model development and technology development can result in a system that meets the needs of the people using it while also being robust in the face of change in the problem domain.
The process side of Domain Driven Design involves the collaboration between domain experts, people who know the problem domain, and the design/architecture experts, people who know the solution domain. The idea is to have a shared model with shared language so that as people from these two different domains with their two different perspectives discuss the solution they are actually discussing a shared knowledge base with shared concepts.
The lack of a shared problem domain understanding between the people who need a particular system and the people who are designing and implementing the system seems to be a core impediment to successful projects. Domain Driven Design is a methodology to address this impediment.
It is more than having an object model. The focus is really about the shared communication and improving collaboration so that the actual needs within the problem domain can be discovered and an appropriate solution created to meet those needs.
Domain-Driven Design: The Good and The Challenging provides a brief overview with this comment:
DDD helps discover the top-level architecture and inform about the
mechanics and dynamics of the domain that the software needs to
replicate. Concretely, it means that a well done DDD analysis
minimizes misunderstandings between domain experts and software
architects, and it reduces the subsequent number of expensive requests
for change. By splitting the domain complexity in smaller contexts,
DDD avoids forcing project architects to design a bloated object
model, which is where a lot of time is lost in working out
implementation details — in part because the number of entities to
deal with often grows beyond the size of conference-room white boards.
Also see this article Domain Driven Design for Services Architecture which provides a short example. The article provides the following thumbnail description of Domain Driven Design.
Domain Driven Design advocates modeling based on the reality of
business as relevant to our use cases. As it is now getting older and
hype level decreasing, many of us forget that the DDD approach really
helps in understanding the problem at hand and design software towards
the common understanding of the solution. When building applications,
DDD talks about problems as domains and subdomains. It describes
independent steps/areas of problems as bounded contexts, emphasizes a
common language to talk about these problems, and adds many technical
concepts, like entities, value objects and aggregate root rules to
support the implementation.
Martin Fowler has written a number of articles in which Domain Driven Design as a methodology is mentioned. For instance this article, BoundedContext, provides an overview of the bounded context concept from Domain Driven Development.
In those younger days we were advised to build a unified model of the
entire business, but DDD recognizes that we've learned that "total
unification of the domain model for a large system will not be
feasible or cost-effective" 1. So instead DDD divides up a large
system into Bounded Contexts, each of which can have a unified model -
essentially a way of structuring MultipleCanonicalModels.
You CAN ONLY understand Domain driven design by first comprehending what the following are:
What is a domain?
The field for which a system is built. Airport management, insurance sales, coffee shops, orbital flight, you name it.
It's not unusual for an application to span several different domains. For example, an online retail system might be working in the domains of shipping (picking appropriate ways to deliver, depending on items and destination), pricing (including promotions and user-specific pricing by, say, location), and recommendations (calculating related products by purchase history).
What is a model?
"A useful approximation to the problem at hand." -- Gerry Sussman
An Employee class is not a real employee. It models a real employee. We know that the model does not capture everything about real employees, and that's not the point of it. It's only meant to capture what we are interested in for the current context.
Different domains may be interested in different ways to model the same thing. For example, the salary department and the human resources department may model employees in different ways.
What is a domain model?
A model for a domain.
What is Domain-Driven Design (DDD)?
It is a development approach that deeply values the domain model and connects it to the implementation. DDD was coined and initially developed by Eric Evans.
Culled from here
Here is another good article that you may check out on Domain Driven Design. if your application is anything serious than college assignment. The basic premise is structure everything around your entities and have a strong domain model. Differentiate between services that provide infrastructure related things (like sending email, persisting data) and services that actually do things that are your core business requirments.
Hope that helps.
As in TDD & BDD you/ team focus the most on test and behavior of the system than code implementation.
Similar way when system analyst, product owner, development team and ofcourse the code - entities/ classes, variables, functions, user interfaces processes communicate using the same language, its called Domain Driven Design
DDD is a thought process. When modeling a design of software you need to keep business domain/process in the center of attention rather than data structures, data flows, technology, internal and external dependencies.
There are many approaches to model systerm using DDD
event sourcing (using events as a single source of truth)
relational databases
graph databases
using functional languages
Domain object:
In very naive words, an object which
has name based on business process/flow
has complete control on its internal state i.e exposes methods to manipulate state.
always fulfill all business invariants/business rules in context of its use.
follows single responsibility principle
DDD(domain driven design) is a useful concept for analyse of requirements of a project and handling the complexity of these requirements.Before that people were analysing these requirements with considering the relationships between classes and tables and in fact their design were based on database tables relationships it is not old but it has some problems:
In big projects with complex requirements it is not useful although this is a great way of design for small projects.
when you are dealing with none technical persons that they don,t have technical concept, this conflict may cause some huge problems in our project.
So DDD handle the first problem with considering the main project as a Domain and splitting each part of this project to small pieces which we are famous to Bounded Context and each of them do not have any influence on other pieces.
And the second problem has been solved with a ubiquitous language which is a common language between technical team members and Product owners which are not technical but have enough knowledge about their requirements
Generally the simple definition for Domain is the main project that makes money for the owners and other teams.
I do not want to repeat others' answers, so, in short I explain some common misunderstanding
Practical resource: PATTERNS, PRINCIPLES, AND PRACTICES OF DOMAIN-DRIVEN DESIGN by Scott Millett
It is a methodology for complicated business systems. It takes all the technical matters out when communicating with business experts
It provides an extensive understanding of (simplified and distilled model of) business across the whole dev team.
it keeps business model in sync with code model by using ubiquitous language (the language understood by the whole dev team, business experts, business analysts, ...), which is used for communication within the dev team or dev with other teams
It has nothing to do with Project Management. Although it can be perfectly used in project management methods like Agile.
You should avoid using it all across your project
DDD stresses the need to focus the most effort on the core subdomain. The core subdomain is the
area of your product that will be the difference between it being a success and it being a failure. It’s
the product’s unique selling point, the reason it is being built rather than bought.
Basically, it is because it takes too much time and effort. So, it is suggested to break down the whole domain into subdomain and just apply it in those with high business value. (ex not in generic subdomain like email, ...)
It is not object oriented programming. It is mostly problem solving approach and (sometimes) you do not need to use OO patterns (such as Gang of Four) in your domain models. Simply because it can not be understood by Business Experts (they do not know much about Factory, Decorator, ...). There are even some patterns in DDD (such as The Transaction Script, Table Module) which are not 100% in line with OO concepts.
I believe the following pdf will give you the bigger picture. Domain Driven Design by Eric Evans
NOTE: Think of a project you can work on, apply the little things you understood and see best practices. It will help you to grow your ability to the micro service architecture design approach too.
Get an organization wide understanding of the problem domain by
developing a ubiquitous language (a common mental model) per sub-problem-domain.
Use that language as close as possible in solution domains (code).
Only then choose technologies.
Don't be technology driven but problem domain or business driven.