We are trying to apply DDD at work, and i'm confused with the way they defined bounded contexts.
They are defining bounded contexts as stakeholders, so in our case we have Customer,Seller, Admin, Sales.
Their argument is, each bounded context has one reason to change (reason as person or a group and thus stakeholders).
The problem is we are duplicating business rules since our bounded contexts are loosely coupled.
So let's say we have a refund use case, Sellers can refund their customers while Admins can refund any customers on behalf of the Seller.
The way we defined our bounded contexts, we are now duplicating the refund business rules.
I don't have a better approach of dealing with this, i'm new to DDD, would like to have some help/clarifications on:
Are bounded contexts supposed to be stakeholders ?
Is business rules duplication an indication of bad design ?
How can we model our bounded contexts to better design Admin refund / Seller refund use cases ?
P.S: it's a monolith app
I'm no DDD-guru but I have some experience with it so I'll give it a shot.
A bounded context is just what the name suggests, a context which is bounded, to a specific domain. It has a specific well-defined language and is designed for specific tasks. It often have aggregates of de-normalized state representing use-cases.
A bounded context in your case may be "RefundHandling" or something like that, with aggregates for perhaps "SellerRefundProcess", and entities or just values for "Seller" etc depending on each use-case.
Bounded contexts should be loosely coupled as you write. That's a big reason for dividing a complex domains into more specific domains focusing on specific tasks/use-cases. But if you have business rules you have to share between these domains, then yes perhaps they are not so different after all. Perhaps your domain could be divided in other ways, if any.
An easier approach would be to share the common rules you have with shared kernel assembly. Not as clean but sometimes it's unavoidable.
Just some thoughts and ideas, for what it's worth.
How would you handle a domain that shares much of the same business logic, but has slight variances in both the domain language and attributes of entities. These variances change by "region".
A fictitious example is a Real Estate System for managing residential Real Estate. The language used can vary slightly between State/Province, and attributes about the Real Estate can be more detailed in some States. There would be an Office in each State/Province managing the Real Estate for that "region".
Would you create a separate Bounded Context for each State/Province? So there would potentially be 50+ Bounded Contexts?
Would you create a single Bounded Context, and just handle the variances of language, and data through object inheritance or composition?
Let me start off by saying that I don't think there's a silver bullet here. As always it all depends on different factors. That's way my reaction is not a concrete idea but rather a set of consideration you and your team could take into account on the path to a decision.
If I would be asked to define a bounded context I would say that it is the setting where a word has a certain meaning or connotation. If we can agree one the above statement then one would immediately be tempted to create a bounded context per region or setting.
That is, if the benefit you gain from having all those context contributes to the comprehensibility of the codebase. But if the context you are creating are really thin or you pay a heavy technical maintenance costs of having all those contexts I would strongly advise against going for multiple contexts.
I'm not certain but I feel that in your case one word will have the same meaning in each context only the word used will be different in each context. Whereas normally the same word used in different contexts has a different meaning.
I hope that this all makes sense and it helps you figure out your issue.
I reached out to Vaughn Vernon, one of the leaders in the area of DDD and I thought I would share his response (summarized by me).
Based on the limited information and examples I provided he brought up these points:
Metadata driven design would be more effective and efficient. Meaning, each "region" would have metadata to drive its flows, and data
Look at the State Pattern to drive regional situations
Look at the concept of DCI for ideas, but limit your attempts at actual DCI implementations as it can increase complexity of the code
How do you plan and divide your application into bounded contexts? On the one hand it's very handy having all this decoupling, but on the other hand too much granularity can lead to a very cumbersome development. Where is this thin line? What factors do you take under consideration when designing your bounded contexts and context maps? Are they technical, strategic maybe?
In a lot of examples you see e-commerce app as a set of bounded contexts: catalog, shopping, invoicing, delivery etc.
Where are those coming from?
Technical, definitely not...
Did you heard about Event Storming ? I think it is a good way to found your boundaries...
Bounded context is about language, it is not technical or architectural think, but more about your domain and the words used by your Domain Expert : Greg Young explain-it well in the beginning of this talk
When you are modelling your Domain Model, you have to define your boundaries (for eCommerce, Product is not the same concept with the same attributes in different contexts : catalog, shopping... The same thing about customer... And you don't have to use the same entity for each context, so every context have its specific Ubiguitous language), think about this activity iteratively (sometime Bounded Contexts emerge and are not clearly visible first)
As soon as you use both same words to define distinct concepts, you are faced to both bounded contexts.
Suppose an application dealing with movies rental.
If your team (business/developers) talk about "Users" to define users in terms of identity and access, and "Users" too to in terms of Renters, then you would have both bounded context:
IdentityAndAccessContext (managing authentication, roles etc.. technical)
MovieRentalContext (unaware of Users, but Renters)
Bounded context is the reflection of the chosen ubiquitous language.
For modeling domain from scratch I think is good decision to start from one bounded context and one module. Than concepts start to conflict or look strange keeped in one module, it's time to separate some concepts into distinct module (or reorganize between modules).
Same approach for separating modules into distinct bounded contexts.
I've been reading Eric Evans' DDD: Tackling Complexity in the Heart of the Software and in the section in context maps, Evans cited an example of 2 bounded contexts (Booking context and Network Traversal Service) using a translator to integrate them.
If I understand correctly, when we create a model, we put everything into bounded contexts creating conceptual boundaries for the domain. My questions are:
If everything should be in a bounded context, where should the translator be located? In Evans' sample diagram, the translator is outside (in between) both bounded contexts.
Say we have a single team working on a ERP. Should the ERP be put in several bounded contexts or a single one only. Based on Evans' sample, the bounded contexts were devised so that multiple teams could work on their own model. But since this is a single team, wouldn't they benefit on a single model so integration wouldn't be an issue? Or did I understand this wrong?
In question 2's case, if multiple bounded contexts, what if in implementation, we need a class from Accounting to be used in Payroll? I don't think we need a translator here but I'm not sure how to share the required class. Will just referencing the needed class from another bounded context be fine?
And lastly, how is a module in DDD related to a bounded context?
In an Infrastructure layer (outside the Domain), it's a technical detail.
A bounded context(BC) emerges from the Domain, that's why we identify them and not defining them. Once identified, if there are many BCs and there are developers available then the workload can be split so that the app can be developed faster. A single model is not advisable, you want a single domain model per BC and also a simplified read model for querying (CQRS).
I don't know but for me Payroll is part of Accounting, there aren't really 2 BC. Account is a BC, however other BC might need a Payroll but that definition is specific to the BC. And probably the definition is just really some data (a read model). Payroll behaviour should stay in Accounting. So you need to have clearly defined what each BC understands by "Payroll". Usually you'll have a domain service who will use concepts from both BC and which will use the 'translator'.
It isn't. A module just groups things together from a technical point of view. A BC is pretty virtual, you might choose to have a project or a module corresponding to one BC but that's your decision how to organize things.
If everything should be in a bounded context, where should the translator be located? In Evans' sample diagram, the translator is
outside (in between) both bounded contexts.
I think this question has no sense. Each BC is a boundary in wich a domain model exist, and the boundary is determined by the UL, each BC has its own UL. If you just create one model, you don't need translation. Instead of spliting a big model into several smaller ones, you are joining them.
Say we have a single team working on a ERP. Should the ERP be put in several bounded contexts or a single one only. Based on Evans'
sample, the bounded contexts were devised so that multiple teams could
work on their own model. But since this is a single team, wouldn't
they benefit on a single model so integration wouldn't be an issue? Or
did I understand this wrong?
I think you understood wrong. You split a single model into several BCs according to the UL, not to the available teams. Then if you don't have enough teams for the number of BCs created, a team will have to develop more than one BC. By the way, the opposite is not desirable, i.e., a BC shouldn't be developped by more than one team.
In question 2's case, if multiple bounded contexts, what if in implementation, we need a class from Accounting to be used in Payroll?
I don't think we need a translator here but I'm not sure how to share
the required class. Will just referencing the needed class from
another bounded context be fine?
You shouldn't reference a domain object of another BC. That BC should protect its domain model, that's the application layer for. The application layer expose DTOs, plain objects, it shouldn't expose the domain model to the outside world. What you are asking for is a shared kernel (a model shared by other BC).
And lastly, how is a module in DDD related to a bounded context?
A module is just a java package, useful for keeping together things that a related to each other. So you split the source code of a BC in modules. Do it according to the UL, not to technical aspects. For instance, a module for each aggregate, not a module for entities, another one for repositories, etc.
I've read Eric Evan's book and am reading Vaughn Vernon's book now. I'm in the second chapter where he talks about subdomains and bounded context and am thoroughly confused now.
From what I was able to distill, there should be a 1:1 relationship between a BC and an SD. However, I read in other places that this isn't necessarily the case.
Can someone explain to me the relationship between a BC and SD?
A subdomain is a part of your business. There are core domains, supporting domains and generic domains. Core domains are where the money is, supporting domains support your core business, and generic domains are the ones you need, but don't care a lot about, so you would probably buy them of the shelf. For an insurance company, the core domain is insurance, a supporting domain could be client portfolio, and a generic domain could be something like timesheets.
In general a bounded context is a boundary within which the ubiquitous language is consistent. In DDD walhalla each subdomain would live in its own bounded context. In reality however, there is legacy, there are packages that try to do everything at once... which will force all kinds of awkard relationships.
I try to explain these concepts with my understanding.
In DDD, everything should be communicated under ubiquitous language so the technical team and business team can use the same terms and have same views on the problems
Domain in DDD represent real problem in business. Such as: E commerce is a domain, Payroll system is a domain
Domain is divided into many sub domains, so each sub domains focus smaller problems. Such as: E commerce has many sub domains such as: Shopping Cart, Billing, Product Catalog, Customer Information...
Each sub domain should have explicit responsibilities so it has a boundary to limit their functionalities, the boundary will help sub domain focus to do only 1 thing and do well. This boundary is considered as bounded context of the sub domain. The bounded context will define:
How many domain models needed for the sub domain?
Which properties needed in the each model?
Which functionalities needed in sub domain?
Ex: Shopping Cart sub domain needs models: Cart, Product, Customer Info... and contains functions to perform CRUD on the cart. Notes: The Product and Customer model in the Shopping Cart sub domain maybe not the same with the models in Product Catalogs and Customer Profiles sub domain, they just contain necessary properties to display on Shopping Cart.
Vaughn Vernon in his “Implementing Domain-Driven Design” book states that “the subdomains live in the problem space and the bounded contexts in the solution space”
Imagine a software that is being developed to support a dentist. A dentist has two problems: fixing patients’ teeth and making appointments for the patients. Fixing teeth is the core domain and making appointments is a supporting subdomain. In the core domain the medical staff cares about a patient’s dental history, can they handle general anesthesia or not, what their current problem is, etc. In the subdomain the staff (not necessarily medical staff) cares about a patient’s contact information, a date and a time that best suits both the doctor and the patient, the type of dental work needed, etc. Both domains need a model of a patient, but that model will depend on the bounded context we put in place to ensure the correct information and features are available when solving the problems of each domain.
read https://robertbasic.com/blog/bounded-contexts-and-subdomains/
Rereading the Booking Context from the blue book 18 times helped me finally get a handle. http://codeidol.com/csharp/domain-driven-design/Maintaining-Model-Integrity/Bounded-Context/
This article helped as well: http://gorodinski.com/blog/2013/04/29/sub-domains-and-bounded-contexts-in-domain-driven-design-ddd/
Here is my understanding, I would use the Hospital example to elaborate the concepts and deep dive into how is BC is different than Subdomain and why they can be a case where there is no 1:1 relationship between them
Example
Imagine we are making software for a Hospital, in which we have identified 3 subdomain
Health Care (Core domain, where they actually want to cure the patient)
Invoice (Supporting domain focused on invoicing)
Knowledge (Generic domain, where doctors maintain procedures on how to operate on a patient for a particular disease)
Now we know that Bounded Contexts are boundaries under which terms
have a very well-defined meaning. So let us apply those in Subdomains
Let's consider the term. Patient. What are the things that you think about when hearing the term patient?
Their current symptoms
Past medical records
Allergies
How about their bill-paying credibility? Current outstanding balance? Didn't think of it? The reason is you were thinking in the core subdomain space of Health Care. The bill-paying credibility makes sense only when you shift to the Invoice subdomain.
What we understand from this is the Patient term is inside a Bounded Context, its a boundary inside a subdomain where it has a very specific meaning
The reason it said
BC is in solution/implementation/programming space and not in business
space
is because here we decide what fields and behaviors should be part of the Patient model
In the core domain space, you might represent Patient it like this
class Patient {
List<Allergy> alergies;
List<MedicalRecord> records;
Age age;
boolean isAllergicTo(Allergy allergy)
boolean canTakeLocalAnesthesia()
}
Whereas in the Invoicing subdomain you might want to represent it like this
class Patient {
CreditCard creditCard;
CreditScore creditScore;
Bill currentBill;
void charge(Amount amount)
}
Similarly, the term Cure in the Health Core subdomain, would have the operations that were/are_to_be performed on a patient to cure the disease whereas in the Knowledge subdomain it would contain information about Symptoms, Diagnosis tests, Prescription suggestions, that go along with a disease.
You can now see the Health Care subdomain has multiple BCs and under a BC each term has a very specific meaning thus supporting the Ubiquitous Language
Please check this link it will help you,
Bounded Context or Context?
The term Context is a general description of a grouping of concepts, the term Bounded Context is more specific – a Bounded Context is an area of your application which has explicitly defined borders, has its own Model, and maintains its own code. Within the Bounded Context everything should be strictly consistent.
Usually, we can use the terms Context and Bounded Context interchangeably, though I tend to talk in terms of Context about the business side of things, and the term Bounded Context about the technical implementation.
In a very short and simple sentence, we can say: subdomains are part of the problem space and are chosen by The Business whereas bounded contexts are software boundaries defined by engineers.
First. The official definitions from the Blue Book is:
Domain: A sphere of knowledge, influence, or activity.
Bounded context: The delimited applicability of a particular model. Bounded contexts gives team members a clear and shared
understanding of what has to be consistent and what can develop
independently.
Note that those concepts exists by themselves before any architecture design or line of code is written down.
DDD is about having a domain model shared by business people and programmers that is reflected in source code. But with medium or bigger organisations it is not practical to have a single model. It is better to divide and conquer because:
Different areas have different needs, cultures, jargon, etc. Sometimes the same concept has different terms or viceversa.
Creating a big meeting to make people agree is costly and it is really hard to agree in something at this scale for so many people.
The cognitive load of developing an enterprise-wide mega application. Better to implement a components that can assigned to smaller teams.
So you reduce the domain modelling to an specific an concrete bounded contexts. This has the advantage of also reducing the complexity. But what if the same concept is used in several contexts? This leads me to the second question:
There should be a 1:1 relationship between a BC and an SD. However, I
read in other places that this isn't necessarily the case.
No. There is no need. Here is an example from Martin Fowler: the products and customers subdomains are shared by the sales and support bounded contexts.
Of course you try to select bounded contexts as loosely coupled as possible. But just as when you separate modules in an app there is a minimum level of coupling to make the connection. So, the same concept is modelled differently in each context (Multiple Canonical Models). This can be implemented in code by adding an Anti-Corruption-Layer that translates between models.
Moving to a single bounded context is not just a matter of software design. It would require modifying the mental model of business and this is hard. Also, people sometimes have simpler views of a domain because it reduces the complexity and their cognitive load.
Concrete example:
In this talks from DDD Europe they have an example from Amazon:
The sub-domain term Book has a very different model in different bounded contexts:
In the Catalog bounded context: Picture, title, authors, rating...
In the Shipping bounded context: Dimensions, weight, international restrictions
In the Search inside bounded context: full-text content, copyright dealing policy
So Amazon may have very complex sub-domains with lots of attributes:
Books: isbn, title, number of pages)
Clothing: size, colour, material
Computers: cpu, graphic card, hard-drive, ram
But only some of them would be relevant in different subdomains.
Let me add a diagram with a more global example
Extra resources:
"Bounded Contexts" Talk by Eric Evans in DDD Europe 2020
DDD Crew: repo resources
Virtual DDD community
Vaughn Vernon states in his book “Implementing Domain-Driven Design” the following:
"It is a desirable goal to align Subdomains one-to-one with Bounded Contexts." Page 57
A model's boundary, the bounded context, can contain ideas from various subdomains. Or a single subdomain might be represented by a number of bounded contexts. The ideal scenario would be one bounded context for one subdomain. If you are able to define multiple bounded context for a subdomain, that sometimes leans you into realizing that the subdomain is not fine-grained, and maybe the subdomain could be distilled into separated subdomains.
The other way around could also be justified, when you had multiple subdomain aspect covered in one BD, because e.g. that was pragmatic to do so.
More specifically, when the subdomain is generic, and the generic solution is easy to integrate, it may be more cost-effective to integrate it in each of the bounded contexts locally.
An example is a logging framework; it would make little sense for one of the bounded contexts to expose it as a service, as the added complexity of integrating such a solution would outweigh the benefit of not duplicating the functionality in multiple contexts.
When two different languages talking the same or similar thing, the thing is referred in 2 different contexts. You can translate the thing in 2 context in certain extents.
Similarly a term could have different meaning in different departments. in that case different context explain the term differently. Translation between two to some extent maybe possible.
Instead of saying “Bounded context” maybe try saying “bounded world”
My understanding about sub-domain and bounded context is-
Each subdomain represents a specific area of knowledge or responsibility within the overall domain, and each subdomain may have one or more responsibilities associated with it. In some cases responsibilities can split across multiple subdomains. Considering all theses issues, it can be useful to draw logical boundaries to separate those responsibilities and maintain consistency and transactional integrity.
Bounded contexts in Domain-Driven Design (DDD) are used to define these logical boundaries and provide a way to manage the complexity of large and complex systems by dividing them into smaller, more manageable parts. By using ubiquitous language we can ensure that the concepts and rules of that context are clearly understood and communicated within the development team. So we draw that boundary based on the uses language in that particular context.
So, in summary, a subdomain represents a specific area of knowledge or responsibility within the overall domain, and bounded contexts are used to manage the complexity of large systems by creating logical boundaries around specific areas of responsibility, and using a specific language, or ubiquitous language, to ensure clear communication and understanding of the concepts and rules within that context.
Bounded context ensure us that one responsibility doesn't blend with another one and finally prevent us from introducing complexity and confusion. In that sense it is very similar with SRP of SOLID