Journal of Distributed Software Engineering, Architecture and Design
Domains, Sub-Domains and Bounded Contexts: Explained with example from industry
<div class="cs-rating pd-rating" id="pd_rating_holder_1819065_post_1408"></div>
<p class="wp-block-paragraph">The Domain Driven Design (DDD) book and community use the language of Domains and Bounded Contexts. Often there is confusion around what is a Domain, Sub-Domain, Bounded Context and how do we tell the difference between one or other when we are in the trenches. </p>
<p class="wp-block-paragraph">This confusion can lead to poor design where our domain or bounded context is not reflecting reality and the software we then build off of it uses a bad model or shows signs of tight-coupling leading to very <em>chatty</em> services between contexts. In this post we pick the example of Insurance Domain and explore some heuristics for determining domains, bounded-contexts before we build our domain APIs and Events </p>
<h2 class="wp-block-heading" id="domain">Domain</h2>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-21-at-12.22.13-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-21-at-12.22.13-pm.png?w=756" alt="" class="wp-image-1843" width="320" height="193" /></a><figcaption>The wikipedia definition of a domain</figcaption></figure></div>
<p class="wp-block-paragraph">Our definition of a domain is in the context of software engineering. In this context, our domain example starts out within a specific <strong>industry</strong> – Insurance, Banking, Education etc because our software is specific to the industry domain</p>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-21-at-12.28.00-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-21-at-12.28.00-pm.png?w=1024" alt="" class="wp-image-1851" width="576" height="415" /></a><figcaption>Industries and Domains</figcaption></figure></div>
<p class="wp-block-paragraph">Looking deeper into an industry vertical (domain) at the next level we can have domains by subject areas or line-of-businesses, which one do we pick?<strong> </strong></p>
<p class="has-text-align-left wp-block-paragraph"><strong>Heuristic 1</strong>: <strong>Follow the funding model</strong></p>
<p class="wp-block-paragraph">If we follow the funding model then business domains make sense at the highest level (e.g LifeInsurance, Vehicle Insurance) vs a functional domain that supports the capability (e.g. Claim, Policy, Document etc). We can then think of the child domains as <em><strong>business oriented functional domains</strong> that help realise <strong>business capabilities</strong></em> (e.g Life Insurance – Claim vs Motor Insurance – Claim vs Vehicle Insurance – Claim)</p>
<p class="wp-block-paragraph"><strong>Heuristic 2</strong>: <strong>Orient domains to business capabilities </strong></p>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-20-at-11.21.35-am.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-20-at-11.21.35-am.png?w=1024" alt="" class="wp-image-1825" width="534" height="414" /></a><figcaption>Child domains such as Claim, Policy, Document within Vehicle, Home, Life business domains</figcaption></figure></div>
<p class="wp-block-paragraph">Notice some domains are core to your business, i.e. they hold the secret-sauce that brings in the revenue while the other domains are supporting</p>
<p class="wp-block-paragraph"><strong>Heuristic 3:</strong> <strong>Know where your secret-sauce is, core domains </strong></p>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-20-at-12.10.54-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-20-at-12.10.54-pm.png?w=1024" alt="" class="wp-image-1827" width="611" height="437" /></a></figure></div>
<p class="wp-block-paragraph">There are also supporting domains which are key to the core-domains delivering value, for example <strong>we need Identity to support </strong>taking Claim and Policy domains online. In a brick and mortar scenario, Identity may not be critical but for an online presence it is key</p>
<p class="wp-block-paragraph"><strong>Heuristic 4:</strong> <strong>Know what you cannot do without, find your supporting domain </strong></p>
<p class="wp-block-paragraph">Finally there are things that you need and generic to all business functions, for example in Insurance context we may need Notification, Document Generation etc. There are your generic domains and support your business functions without specific context (<strong>re-useable?</strong>) </p>
<p class="wp-block-paragraph"><strong>Heuristic 5:</strong> <strong>Know what is common across one or more domains and generic, build common services for these for all others to use </strong></p>
<p class="wp-block-paragraph"><strong>Note</strong>: <em>The classification of core, supporting and generic is applicable in a business function context. For example, if we divide a domain further into core, supporting and generic then it has to be for business reasons, in which case one might argue why it the inner core domain is not pulled up</em></p>
<p class="wp-block-paragraph">Warning: <em>Generic domains are notorious breeding grounds for your monolithic software of the future. These can start our context-free and over time contextual logic can creep-in, for example – a Notification service mutates from being generic to using specific Email templates and Branding depending on the context. The act of changing the Notification API to accept new attributes for branding or email templating can become contentious and cause impact across line-of-businesses within an enterprise </em></p>
<h3 class="wp-block-heading" id="bounded-contexts">Bounded Contexts</h3>
<p class="wp-block-paragraph">A Bounded context is a term from Domain Driven Design (DDD) and represents a linguistic boundary within or across a domain. While the statement “<em>this is where there is a ubiquitous language</em>“, sounds trivial there are several traps: </p>
<ul class="wp-block-list"><li>Linguistic boundary depends on who we sanction to tell us the language – who is the true domain expert?</li><li>Depending on which definition of language we pick the linguistic boundary could be wide, as wide as a large domain or even across domains (see 3 choices below). This would make the model bloated and would introduce strong coupling</li><li>Language applied to some entities may have a common model (e.g. Reporter Contact in Lodgement and Management of a claim) making us believe the bounded context extends wider ( e.g making Lodgement & Management context). We need to examine the language for all entities (e.g Claim in Lodgement is a small model vs in Claim Management which is the full claim object)</li></ul>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-21-at-6.24.41-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-21-at-6.24.41-pm.png?w=1024" alt="" class="wp-image-1853" width="484" height="407" /></a></figure></div>
<p class="wp-block-paragraph"><strong>We have 3 possible choices for drawing boundaries</strong></p>
<ul class="wp-block-list"><li><strong>Context spans the domain</strong>: e.g. Claims domain speaks the language of the NSW Motor Vehicle Claim laws</li><li><strong>Multiple Contexts within the domain</strong>: e.g. Claim Lodgement and Management, Claim Owner Registration</li><li><strong>Context spans multiple domains</strong>: e.g There is a NSW Motor Vehicle P&C law and the language in the 2 domains for policy buying, claim lodgement etc uses the vocabulary of the book</li></ul>
<p class="wp-block-paragraph">In our insurance example then, we apply the heuristics for bounded contexts and make sure they are not too big or not too small to end up with something like the picture below. Notice how the all domains have multiple bounded contexts (models) and we have <em>split</em> the “lodgement and management” context into 2 (despite both of them defining the contact entity in the same way)</p>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-20-at-2.37.44-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-20-at-2.37.44-pm.png?w=1024" alt="" class="wp-image-1829" width="572" height="434" /></a><figcaption>Sample set of bounded contexts for Vehicle Insurance with representation of a Contact</figcaption></figure></div>
<h3 class="wp-block-heading" id="apis-events-and-services">APIs, Events and Services</h3>
<p class="wp-block-paragraph">The <em>interaction</em>s across bounded contexts happens with the exchange of a model – one sends its internal representation of a concept across to another or consumes a model from another. DDD context interaction patterns describe these as “Upstream” or “Downstream” relationships and help show where an external model is influencing a bounded context</p>
<figure class="wp-block-image size-large"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-21-at-6.49.31-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-21-at-6.49.31-pm.png?w=1024" alt="" class="wp-image-1857" /></a><figcaption>Domain events, commands, queries across contexts</figcaption></figure>
<p class="wp-block-paragraph">These interactions not only help with designing services but using the DDD context mapping notation we can define power relationships and discover the information models we need to propagate</p>
<p class="wp-block-paragraph">We need to also model the <strong>transactional</strong> state of the system as we build the cross-context interactions. This means that we need to be asking if the consistency requirements are real-time or can they be eventual because incorrect integration pattern here could stop a business functionality. For example, imagine having to update the customer management context in real-time via an API (POST /api/customer/contacts) every time we are in a Policy buying or renewal transaction step. The <strong>strong coupling </strong>could cause the Policy buying and renewal to fail if there are network or data validation issues in the customer context</p>
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-20-at-2.42.18-pm.png"><img src="https://alok-mishra.com/wp-content/uploads/2021/04/screen-shot-2021-04-20-at-2.42.18-pm.png?w=686" alt="" class="wp-image-1831" width="338" height="350" /></a><figcaption>How do we interact across contexts? How do we propagate a model?</figcaption></figure></div>
<h2 class="wp-block-heading" id="summary">Summary</h2>
<p class="wp-block-paragraph">We use domain driven design to discover our business Domains, Bounded Contexts, Models and Interactions to build better distributed software features which would be cohesive within contexts and decoupled across boundaries leading to nimble, changeable modules that can deliver iterative value over time</p>
<p class="wp-block-paragraph">In this post we used a sample industry vertical (Insurance) to do <strong>strategic</strong> DDD. The next step is to get into details: this is <strong>tactical</strong> DDD where teams continue to do domain storytelling, define the details of the models (domain aggregates, value objects etc) and identity commands, queries and events. Finally we take these and engineer the solutions – i.e. apply API, Event and Systems Integration patterns and best practices to build the integrations </p>
The Domain Driven Design (DDD) book and community use the language of Domains and Bounded Contexts. Often there is confusion around what is a Domain, Sub-Domain, Bounded Context and how do we tell the difference between one or other when we are in the trenches.
This confusion can lead to poor design where our domain or bounded context is not reflecting reality and the software we then build off of it uses a bad model or shows signs of tight-coupling leading to very chatty services between contexts. In this post we pick the example of Insurance Domain and explore some heuristics for determining domains, bounded-contexts before we build our domain APIs and Events
Domain
The wikipedia definition of a domain
Our definition of a domain is in the context of software engineering. In this context, our domain example starts out within a specific industry – Insurance, Banking, Education etc because our software is specific to the industry domain
Industries and Domains
Looking deeper into an industry vertical (domain) at the next level we can have domains by subject areas or line-of-businesses, which one do we pick?
Heuristic 1: Follow the funding model
If we follow the funding model then business domains make sense at the highest level (e.g LifeInsurance, Vehicle Insurance) vs a functional domain that supports the capability (e.g. Claim, Policy, Document etc). We can then think of the child domains as business oriented functional domains that help realise business capabilities (e.g Life Insurance – Claim vs Motor Insurance – Claim vs Vehicle Insurance – Claim)
Heuristic 2: Orient domains to business capabilities
Child domains such as Claim, Policy, Document within Vehicle, Home, Life business domains
Notice some domains are core to your business, i.e. they hold the secret-sauce that brings in the revenue while the other domains are supporting
Heuristic 3:Know where your secret-sauce is, core domains
There are also supporting domains which are key to the core-domains delivering value, for example we need Identity to support taking Claim and Policy domains online. In a brick and mortar scenario, Identity may not be critical but for an online presence it is key
Heuristic 4:Know what you cannot do without, find your supporting domain
Finally there are things that you need and generic to all business functions, for example in Insurance context we may need Notification, Document Generation etc. There are your generic domains and support your business functions without specific context (re-useable?)
Heuristic 5:Know what is common across one or more domains and generic, build common services for these for all others to use
Note: The classification of core, supporting and generic is applicable in a business function context. For example, if we divide a domain further into core, supporting and generic then it has to be for business reasons, in which case one might argue why it the inner core domain is not pulled up
Warning: Generic domains are notorious breeding grounds for your monolithic software of the future. These can start our context-free and over time contextual logic can creep-in, for example – a Notification service mutates from being generic to using specific Email templates and Branding depending on the context. The act of changing the Notification API to accept new attributes for branding or email templating can become contentious and cause impact across line-of-businesses within an enterprise
Bounded Contexts
A Bounded context is a term from Domain Driven Design (DDD) and represents a linguistic boundary within or across a domain. While the statement “this is where there is a ubiquitous language“, sounds trivial there are several traps:
Linguistic boundary depends on who we sanction to tell us the language – who is the true domain expert?
Depending on which definition of language we pick the linguistic boundary could be wide, as wide as a large domain or even across domains (see 3 choices below). This would make the model bloated and would introduce strong coupling
Language applied to some entities may have a common model (e.g. Reporter Contact in Lodgement and Management of a claim) making us believe the bounded context extends wider ( e.g making Lodgement & Management context). We need to examine the language for all entities (e.g Claim in Lodgement is a small model vs in Claim Management which is the full claim object)
We have 3 possible choices for drawing boundaries
Context spans the domain: e.g. Claims domain speaks the language of the NSW Motor Vehicle Claim laws
Multiple Contexts within the domain: e.g. Claim Lodgement and Management, Claim Owner Registration
Context spans multiple domains: e.g There is a NSW Motor Vehicle P&C law and the language in the 2 domains for policy buying, claim lodgement etc uses the vocabulary of the book
In our insurance example then, we apply the heuristics for bounded contexts and make sure they are not too big or not too small to end up with something like the picture below. Notice how the all domains have multiple bounded contexts (models) and we have split the “lodgement and management” context into 2 (despite both of them defining the contact entity in the same way)
Sample set of bounded contexts for Vehicle Insurance with representation of a Contact
APIs, Events and Services
The interactions across bounded contexts happens with the exchange of a model – one sends its internal representation of a concept across to another or consumes a model from another. DDD context interaction patterns describe these as “Upstream” or “Downstream” relationships and help show where an external model is influencing a bounded context
Domain events, commands, queries across contexts
These interactions not only help with designing services but using the DDD context mapping notation we can define power relationships and discover the information models we need to propagate
We need to also model the transactional state of the system as we build the cross-context interactions. This means that we need to be asking if the consistency requirements are real-time or can they be eventual because incorrect integration pattern here could stop a business functionality. For example, imagine having to update the customer management context in real-time via an API (POST /api/customer/contacts) every time we are in a Policy buying or renewal transaction step. The strong coupling could cause the Policy buying and renewal to fail if there are network or data validation issues in the customer context
How do we interact across contexts? How do we propagate a model?
Summary
We use domain driven design to discover our business Domains, Bounded Contexts, Models and Interactions to build better distributed software features which would be cohesive within contexts and decoupled across boundaries leading to nimble, changeable modules that can deliver iterative value over time
In this post we used a sample industry vertical (Insurance) to do strategic DDD. The next step is to get into details: this is tactical DDD where teams continue to do domain storytelling, define the details of the models (domain aggregates, value objects etc) and identity commands, queries and events. Finally we take these and engineer the solutions – i.e. apply API, Event and Systems Integration patterns and best practices to build the integrations
Alok brings experience in engineering and architecting distributed software systems from over 20 years across industry and consulting. His posts focus on Systems Integration, API design, Microservices and Event driven systems, Modern Enterprise Architecture and other related topics
View all posts by alokmishra