If someone asks you the meaning of a word, most of the times you don’t have an absolute meaning and end up asking for the context in which it is used. You need to know the context to get to the correct meaning. Similarly, to know your domain model right, you get to know the bounded context it is in.
Let us understand the path that lead to bounded contexts.
We started with procedural programming where execution happens linearly from Main function. The disadvantages of procedural programming are no security, difficult to maintain, difficult to understand and difficult to relate with the real world.
To overcome the above disadvantages, we moved to Object Oriented Programming. This is good and fixed most of the issues with procedural programming. It seems to be connected with the real world but is it for real?
Then there is waterfall method, for a long time, to execute the project but set back with the disadvantages — no working software is produced until late during the life cycle, high amounts of risk and uncertainty, not suited to allow changes in requirements, the gaps are found very late, etc. Once the design phase is done, the Business is not involved in project execution which is high risk.
To overcome the above disadvantages, we moved to Agile methodology. Agile makes everyone (Business, Analysts, Designers, Developers and Testers) involved in the project execution from beginning till end. So, all the teams need to be on the same page.
In Object Oriented Programming, the software seems to be connected with the real world. But it is limited to only the world of application designers. It matched with only his vision of the world. The way he sees it. It did not match with the real world of Business. So, the Business and Analysts/Designers/Developers are never on the same page.
As Agile demands everyone to be on the same page, the Business and Analysts/Designers/Developers should be working on the same world. This is where the Domain-Driven Design comes into picture.
Domain-Driven Design is an approach to software development that is centered on business domain. Domain driven design combines design and execution, facilitates design and development go together to create a better solution. Good design will fasten the development, while feedback coming from the development process will lead the execution in the right direction.
Everyone needs to be involved — domain experts, design experts, developers, etc. in designing the Model.
The domain experts see that the Model reflects the business. The developers will have a say if the design is implementable or not. Domain experts, design experts, developers and testers use a ubiquitous language to discuss and design the Model.
The Model must be consistent, unified and pure. This is achieved by Bounded Contexts.
Why we need Bounded Contexts
Let us consider an enterprise application in telecom domain. There will be more than 70 applications in the system. Imagine 70 applications has to integrate successfully to run the business. It starts with a person approaching the service provider like Airtel, Jio, etc. for new connection. The moment he approaches the service provider, he will be considered as a Lead. He is not the customer yet. If he shows interest in any plan, he will be considered as an Opportunity. His details will go to application verification systems. If everything is fine, the helpline guy or the sales guy will call and confirm his plan. Once he confirms a plan, he will be provisioned into the system. Then he becomes a customer. His account will be created in a profile application. Note that the same person is identified as Lead, Opportunity and Customer in different applications.
His details are captured in CRM — customer relationship management system, billing system, Sales and Marketing System, Packages Management System, Fraud management System, Inventory Systems, Analytics tools, Dealer management systems, Secondary Sales systems, Revenue Leakage tools, Debt Management Systems, etc.
Now imagine if you want a single model — customer in this Enterprise application. The leads and opportunities system will be interested in details like what is his existing service provider, through which channel did he get to know about us, etc. Profiling and the Account Creation systems will be interested in other details like name, address, age, profession, etc. The CRM system might be interested if there are any previous service tickets raised by the person. Sales and marketing team will be interested in his profile and usage details to get an idea on what packages could be recommended to him down the line. Billing System will be focused on billing address and payment mode, etc. Similarly, the Fraud Management system, Inventory systems, the analytics tools, etc. will be interested in other details.
Imagine how confusing your model will be if it includes all these details. The address required for Billing application is billing address. For profiling system or CRM application, it will be current address and permanent address. If the same model is used across the system, at some point of time, Billing team could feel that naming the address field as billing address is more appropriate than current address and rename the current address field to billing address. The model integrity is compromised which in turn breaks the system. So, when the Billing team says address, it might be billing address and when the CRM team says address it might be mailing address. The CRM team is not aware of the billing address and the Billing team might not be aware of the other addresses. If these two teams discuss with each other on the model you could guess the confusion it creates because of the conceptual differences.
Even if both the addresses are saved as different attributes, the Billing address will be redundant and irrelevant to Profiling and other applications.
The same person is a Lead in Leads application and Opportunity in Opportunities application. He is a customer in the provisions and accounting systems. In case he did not pay the bills, he will be a defaulter in another system. If you observe, the same person details are interpreted differently in different applications based on the context. This is where the bounded contexts come into picture.
Sales team cannot go to Leads/Opportunities team and ask for the customer details because their model is not supposed to have Customers but instead have Leads / Opportunities. They will understand only if you ask for the leads or opportunities details.
To get rid of these, you need to define the boundaries to your model and confine it to a context. Otherwise there will be a lot of confusion and chaos that creeps into your system and makes the model unmanageable and impure.
Model
You might be wondering what is Model.
Don’t confuse model with the class in Object Oriented Programming. The Model in a Domain-Driven Designed project is your solution to the problem.
The Model usually represents a Business solution in its own language and concepts. In a complex enterprise application, it might be a simplification of a bigger picture so that the important concepts are focused and not so important details are ignored.
This means your Model should be focused knowledge around a specific problem that is simplified and structured to provide a solution. There are patterns to design a model. Here are the building blocks of a model-driven design.
· Layered Architecture
· Entities
· Value Objects
· Services
· Modules
· Aggregates
· Factories
· Repositories
For the time being understand that the model represents a solution to the problem. The Customer mentioned in the above section will be an entity in the Domain Model.
What is Bounded Context
A Bounded context is the logical frame in which the model evolves. It gives your model the boundaries and determines the kinds of translations permitted between the boundaries.
A large system needs to have multiple models. Each model needs to be consistent and pure. It should have the data related to its bounded context only and ignore the data related to other contexts.
For example, every application mentioned in the above example like Leeds, Profiling, CRM, Billing have different models. They might be connecting to the same database but still have different models. Billing related data is never included in CRM Model or vice versa.
Suppose there is a reporting system which needs to report billing details of a customer. The reporting system needs two additional fields to be added to the customer entity in Billing Model. There will be a normal tendency to add these fields to the customer entity in the Billing Model and use the same in Reporting Model. This violates the rule that Billing Model should consist only the data related to its context but not the data related to Reports Model. So, the reporting team is not allowed to tweak the customer entity in Billing Model. The Billing Model bounded context does not allow this.
The boundary or the logical frame which help the model to maintain its integrity is called bounded context.
Here is a picture representing bounded contexts providing logical frames to the different models. The integration of all these models provides the required solution. This is achieved by the translation/context maps as shown in the below diagram.
The boundaries could be set based on
o Team Organization — A model should be small enough to be assigned to one team.
o Specific parts of the application
o Physical location of code base
o Database schema
A Bounded Context clearly marks the applicability of a model in an application and how it relates with other contexts so that domain experts, designers, developers and testers have a common understanding of the model and its applicability. Do not bother about its applicability in other contexts. Other contexts have their own models with different terminologies with its own concepts and rules. Having an explicit boundary preserves the model integrity and maintains the consistency of the model keeping it unified and pure.