03 Bounded Contexts Defining Domain Boundaries as Levers

03 Bounded Contexts - Defining Domain Boundaries as Levers #

Hello, I am Ouchuangxin. Today we will focus on the concept of “limiting context.”

In the process of DDD domain modeling and system development, there are many participants, including domain experts, product managers, project managers, architects, development managers, and test managers, among others. Different participants may have different understandings of the same domain knowledge, which can create barriers in communication. So what can we do about it? Therefore, in DDD, the concepts of “ubiquitous language” and “limiting context” are introduced.

These two concepts complement each other. Ubiquitous language defines the context meanings, while limiting context defines the domain boundaries to ensure that each context meaning has a unique interpretation within its specific boundary. The domain model exists within this boundary. Do you feel that this description is quite abstract? Don’t worry, I will explain it to you in detail one by one.

Before that, I would like you to look at these two questions, which are also the core of today’s content.

  1. Why is the concept of limiting context introduced (besides the general reason of solving communication barriers, are there more specific reasons)?
  2. What is the role and significance of limiting context in microservice design?

What is Common Language? #

To better understand the context, let’s start with the concept of Common Language.

How do we understand the concept of Common Language? During the event storming process, the language that can be used to achieve consensus through team communication, and can describe the business meaning and rules in a simple, clear, and accurate way, is the Common Language. In other words, the Common Language is the unified language used in the team, regardless of the roles you play in the team, for communication throughout the software lifecycle within the same domain.

So, the value of Common Language is clear - it can solve the problem of communication barriers, enabling domain experts and developers to collaborate and ensure the correct expression of business requirements.

However, the understanding of this concept is not enough at this point.

Common Language includes terms and use case scenarios and can be directly reflected in the code. Nouns in the Common Language can be used to name domain objects, such as “product” and “order”, corresponding to entity objects, while verbs represent an action or event, such as “product placed order” and “order paid”, corresponding to domain events or commands.

Common Language runs through the entire design process of Domain-Driven Design (DDD). As a unified language formed through project team communication and negotiation, based on it, you can develop code that is more readable and accurately translates business requirements into code design.

Now, let me show you a diagram that describes the complete process from event storming to establishing a Common Language, and then to domain object design and code implementation.

img

  1. During the event storming process, domain experts work together with designers and developers to establish a domain model, which generates common business terms and user stories during the domain modeling process. Event storming is also a process of forming a unified language within the project team.
  2. User story analysis will generate domain objects, each of which corresponds to a business object in the domain model, and each business and domain object has common terms that are mapped one-to-one.
  3. Microservice code models come from the domain model, and each code model’s code object corresponds to a domain object one-to-one.

Here I would like to share a useful tip that I often use, which is quite effective. During the design process, we can use tables to record the domain objects and their attributes generated during event storming and microservice design processes. For example, the position, attributes, dependencies of domain objects in the DDD layer architecture, as well as the mapping relationship with code model objects, can all be recorded in these tables.

Below is a partial dataset from a microservice design example. The terms in the table are the Common Language that the project team has reached consensus on and can be used for internal communication within the team during the event storming process. In this table, we can see that all the domain objects in the DDD analysis process and their attributes are recorded. In addition to the domain objects in DDD, we also record the code objects corresponding to the domain objects in the microservice design process and map them one-to-one.

img

At this point, I want to emphasize again. Every aspect of the DDD analysis and design process needs to ensure the consistency of the terminology within the bounded context. During the code model design, it is necessary to establish a one-to-one mapping between domain objects and code objects to ensure the consistency between the business model and the code model and achieve unity between the business language and the code language.

If you have achieved this, that is, established the mapping relationship between domain objects and code objects, then you can guide software developers to complete microservice development accurately and without error according to the design documentation. Even business people who are not familiar with code can quickly find the location of the code.

What is Bounded Context? #

So what is Bounded Context that was just mentioned for?

We know that languages have their semantic contexts, and universal languages also have their own contextual environments. To avoid ambiguity of the same concept or semantics in different contextual environments, Domain-Driven Design (DDD) introduces the concept of “Bounded Context” in strategic design to determine the domain boundary where the semantics reside.

We can break down Bounded Context into two words: Bounded and Context. Bounded refers to the boundary of the domain, while Context refers to the semantic environment. Through the Bounded Context of a domain, we can communicate in a unified language within the unified boundary.

In sum, I believe the definition of Bounded Context is: used to encapsulate the universal language and domain objects, provide a contextual environment, and ensure that certain terms, business-related objects, etc. (universal language) within the domain have a precise meaning without ambiguity. This boundary defines the scope of the model, allowing all team members to clearly know what should be implemented in the model and what should not be implemented.

Further Understanding of Bounded Context #

We can further understand this concept through some examples. Don’t underestimate it, thoroughly understanding it will lay a solid foundation for your later DDD practice.

It is said that the Chinese language is very rich. In different time and background, the same sentence can have different meanings. There is an example you should have heard of.

On a beautiful morning, a child asked his mother when getting up, “How many clothes should I wear today?” The mother answered, “Wear as much as you can!”

So should the child wear more or less?

Without a specific semantic context, it’s really hard to understand. However, if you already know the semantic context of this sentence, such as in the dead of winter or in scorching summer, then understanding the meaning of this sentence will be easy.

So language cannot be separated from its semantic context.

And the universal language of business has its own business boundaries. It is unlikely that we can describe a complex business domain with a simple term without ambiguity. Bounded Context is used to partition the domain, thus defining the boundary of the universal language.

Now let’s use an example in the insurance domain to illustrate the boundary of terms. In the insurance business domain, there are insurance terms such as application form, policy, endorsement, claim, etc., which are used in different insurance business processes.

  1. When a customer applies for insurance, the business personnel record the application information, and the system corresponds to the entity object of the application form.
  2. After payment is completed, the business personnel convert the application form into a policy, and the system corresponds to the entity object of the policy, with a relationship between the policy entity and the application form entity.
  3. If the customer needs to modify the policy information, the policy becomes an endorsement, and the system corresponds to the entity object of the endorsement, with a relationship between the endorsement entity and the policy entity.
  4. If the customer claims for compensation, a claim is generated, and the system corresponds to the entity object of the claim, with a relationship between the claim entity and the policy or endorsement entity.

Application form, policy, endorsement, claim, etc., although all related to policies, cannot apply the term “policy” to the entire insurance business domain. Because terms have their boundaries, problems will arise if they are understood beyond those boundaries.

If you are not familiar with the insurance industry that I am involved in, that’s okay. You must be very familiar with e-commerce, right?

Just like products in the e-commerce domain, products have different terms at different stages. They are called “goods” during sales and become “cargo” during transportation. The same thing, due to the different business domains, gives different meanings and responsibilities to these terms. This boundary can become the boundary for future microservice design. Seeing this, I think you should be very clear that domain boundaries are defined through Bounded Context.

Relationship Between Bounded Context and Microservices #

Next, let’s further extend this concept and see the specific relationship between bounded context and microservices.

I believe you have either purchased car insurance or heard of it. The car insurance underwriting process includes several main steps, such as application, premium payment, policy issuance, etc. If there is an accident, there are also claim handling processes such as reporting, investigation, assessment, settlement, etc.

The insurance field is quite complex. Here, I will use a simplified insurance model to illustrate the relationship between bounded context and microservices. We will also use some basic knowledge we learned in [Lesson 02], such as domain and subdomain.

img

First, a domain can be divided into multiple subdomains. A domain represents a problem domain, and dividing a domain into subdomains is the process of breaking down a big problem into smaller problems. In this diagram, the insurance domain is divided into four subdomains: application, payment, policy management, and claims.

Subdomains can be further divided into sub-subdomains if needed. For example, the payment subdomain can be further divided into sub-subdomains for receiving payments and making payments. When divided to a certain extent, the domain boundaries of some sub-subdomains may become the boundaries of bounded contexts.

A subdomain may contain multiple bounded contexts. For example, the claims subdomain includes multiple bounded contexts such as reporting, investigation, and assessment (the bounded context boundaries overlap with the sub-subdomain boundaries of claims). It is also possible that the boundary of a subdomain itself is the boundary of a bounded context, such as the application subdomain.

Each domain model has its corresponding bounded context, and the team communicates in a common language within the bounded context. The domain models of all bounded contexts within a domain constitute the domain model of the entire domain.

In theory, bounded contexts are the boundaries of microservices. By mapping the domain models within bounded contexts to microservices, we complete the transition from the problem domain to the software solution.

It can be said that bounded contexts are the main basis for the design and decomposition of microservices. In the domain model, without considering other external factors such as technological heterogeneity and team communication, a bounded context, in theory, can be designed as a microservice.

However, I still need to remind you that apart from theory, there are many limiting factors in the decomposition of microservices, and excessive decomposition should be avoided in the design. So, how do we find the right balance? I will explain the design and specific decomposition methods of microservices in detail in the practical section.

Summary #

A common language determines the unified language for internal communication within a project team, and the semantic context in which this language is located is defined by the bounded context to ensure semantic uniqueness.

The main work of domain experts, architects, and developers is to divide bounded contexts through event storms. Bounded contexts determine the direction of microservice design and decomposition and are the main basis for microservice design and decomposition. If other external factors such as technical heterogeneity and team communication are not taken into account, theoretically, a bounded context can be designed as a microservice.

It can be said that bounded contexts are of great significance in microservice design. If the direction of the bounded context deviates, the design result of the microservice can be imagined. Therefore, only by understanding the true meaning of bounded contexts and their role in microservice design can we truly leverage the value of DDD. This is the foundation and premise.