Bounded Context Patterns

After a decade of coding, I tend to believe that being able to discover and implement correctly bounded context is one of the main values I can bring to a company in my daily job. As a consultant I have the chance to do it in different gigs since a few years now, and I start to see repetitive patterns in the way companies are structured. I usually use a strategic Domain Driven Design (DDD) approach to understand and classify this structure, resulting in some domains, subdomains and bounded contexts. 
Because of this repetition, I think bounded contexts can be classified in patterns, and that these patterns can help to know the importance of the bounded context and how to build it in the most efficient way for the business. 
 
I believe these patterns can also be seen with a hexagonal approach. Indeed, like in the hexagonal architecture, we have core stuff and surrounding stuff with adapters and/or anti-corruption layer. It’s the same principle, just at a different scale. 

Here is a list of the most recurring patterns I have discovered over time. 

The Data loader Context 

It is quite common for a business to be dependent on data from an external source. This is when we require to fetch data from somewhere else, usually at a recurring period.
When I identify this pattern, I try to isolate this behavior in a context, ideally one project per data source. All these projects are Data Loaders for our domain. These contexts are often quite technical and requires a strategy to handle the external (and usually unreliable) data source. 

This image has an empty alt attribute; its file name is image-4.png

The Referential Context  

This a very tricky and still very common one. It is the famous “Tools” or “Common” you’ll find in any solution, but at a different scale. It’s usually a referential of something, that you need to share with the rest of the company, or even with other companies. You know that you should avoid it, but still you really need the whole business to share this single source of truth.
Of course, you want to isolate this behavior in a single context, and then you should not consider it as a “safe” context, because it will have many dependencies. If possible, make this context independent of its consumers, at least the dependencies will go only in one direction.
It’s a very challenging context, because of the dependencies. You need to talk a lot, with lots of team. They are also usually technical, because to make them more Domain Driven you’ll need to know why your data are used. And this is not often compatible with the will of staying independent of the consumers.


The Anti Corruption Context 

Because external data fetching is common, we need to convert them from something not trusted to something validated for our business. It is well known in the DDD community and usually implemented through what is called an Anti Corruption Layer
But I believe that it often makes sense to actually consider this layer as a context by itself, because the logic behind data conversion of an external source can be pretty complicated. Even if the business will tell you that “this is just a JSON you know”… 
This context is at the border between the external/technical world and the internal/domain world. It maps the technical validated data from the Data Loader to something usable by the domain. It is an adapter in the hexagonal architecture metaphor. 

The Reporting Context 

Here comes another almost unavoidable one: the reporting context. It “just” reports data from the core domain and we should not have a high level of domain complexity for that…But still, in my experience they are important because they are used to drive the company and some critical business decisions might depend on it.
And they can also be complex because it is not uncommon to handle automatic integration of this report with external tools, or different access type to the data depending on the user role. 
As explained by Scott Wlaschin in Domain Modeling Made Functional, this is where you’ll put the OLAP responsibility of your system. Whereas the business core is more like an OLTP system. It explains for me why you want to isolate both behaviors.
It is a port to the external world in the hexagonal architecture metaphor. 
 

The Business Core Context 

And finally, the holy grail, the one you look for because it creates value for your business, the key technical asset for your company: the business core context. 
All the projects I have worked with have a business core context. The thing is that most of the time, we put too much things inside (like the data loading or the anti-corruption or the reporting…)  
This is usually done for the sake of Don’t Repeat Yourself (DRY): we have the JSON from this external source, why should we transform it before use it?  This is the usual doom of DRY leading to technical issue leaking into your business, and that’s why you want to avoid it. 
This context should be the more Domain Driven of your whole solution, meaning for example that you want to avoid primitive types, dependencies to external stuff, or not handled exceptions. You shouldn’t do technical validation either, because other contexts can take care of that for you.
In the hexagonal metaphor, it is of course the core domain layer of the architecture. 

Map with core, generic and support contexts

In the DDD community, based on the already mythic blue book by Eric Evans, we usually classify contexts in three categories: core, support or generic. Of course, these categories will depend on your domain, but I think we can most of the time map them with the patterns define above. 
For instance, The Data Loader and the Reporting context can be generic contexts, but again beware of the hiding complexity in it (a third part tool might do the job, at least to start).
The Anti Corruption contexts are usually in the support category (useful but not a competitive advantage, still cannot be done by a third part tool, because it depends on your core domain).
The Referential Context might be core or support.
The Business Core Context is obviously in the core category. 

What next ?

Here are the main patterns that make sense for me so far. This is non exhaustive, for example another pattern I omit is the User Interface (UI) context. Because in which context your UI belongs to isn’t an easy topic in DDD, and one answer to this complex question can be a dedicated context to handle it. But I still don’t really know if it is a useful or a harmful pattern… I tend to prefer context like reporting with a clear business responsibility and usually many UIs.

Anyway, what about your experience? Maybe you have identified some patterns that are missing here? Maybe you know about some blog post or books exploring this part of strategic DDD patterns?
I’ll be glad if you accept to share it with me, and maybe we could build together a more exhaustive (and hopefully useful) list of bounded context patterns? 
 
 

 

Micro-service and bounded context clarification

One micro-service should cover one bounded context” asserts Vaughn Vernon.

It leads to an interesting tweeter discussion with Greg Young, Romeu Moura and Mathias Verraes.  Greg and Romeu disagree. I say it depends of the context.

To know if one can cover another, we must know what a micro-service is and what a bounded context is. I find their definitions are fuzzy, and I think this discussion is a proof of that. I’ll try to clarify my point in this article.

Disclaimer: the following definitions are based on my current understanding of DDD strategic patterns, I don’t claim they are the only true definitions.

twitter-messagerie-logo

Micro-service definition

We believe we know what is a micro-service until we take a look at the Wikipedia definition.

In contrast to SOA, micro-services gives an answer to the question of how big a service should be and how they should communicate with each other. In micro-services architecture, services should be small and the protocols should be lightweight.”

This definition is symptomatic of our industry: we explain something by something else we don’t understand either. Do we share a common understanding of what is “small” and “lightweight”? I don’t think so.

A better explanation is the second property in the details of the Wikipedia page: “Services are organized around capabilities, e.g., user interface front-end, recommendation, logistics, billing, etc.

To be fair, this property has lots of symmetries with how we define a bounded context.micro-services1-297x250

Domain definition and problem space

To understand what a bounded context is, we need to define what a domain is. It is a theoretical representation of a business, in the problem space. And it can be divided in sub-domains.

For example in the well-known business of Amazon,  the core domain is about selling stuff online, and there are different sub-domain more or less generic like shipping, billing, advertising and so on.

We are in the problem space because we have no idea (yet) about how we should implement Amazon’s business, it is just a theoretical description of what they do.

problem
DDD patterns that are applicable to the problem space (figure 1-4 page 10 of PPP of DDD)

Bounded context definition and solution space

A bounded context is a projection in the solution space to define boundaries in the system implementing the domain. Bounded contexts are important because they allow to define an ubiquitous language, valid within their boundaries. A product in a billing bounded context has not the same meaning than in a shipping bounded context.

When it is badly done, we obtain a big ball of mud, e.g. a huge system without boundaries where an update in the billing part may cause side effect in the shipping part.

We are in the solution space because it is an actual description of how we implement the domain. A bounded context does not necessarily matches exactly one sub domain. But having too many bounded contexts overlapping between different sub-domains is definitely a design smell.

solutionDDD patterns that are applicable to the solution space (figure 1-5 page 10 of PPP of DDD)

One micro-service should cover one bounded context?

Now that we defined micro-service and bounded context, we can try to decide if one micro-service should cover one bounded context?

And of course, we still cannot decide, because we still lack the (business) context. In some business context, a micro service might fit a bounded context. In some other, several micro services will be in one bounded context. The only thing we can suppose is that a micro service overlapping different bounded contexts has something wrong.

As usual in any DDD discussion, context is king.

For more thougths on bounded contexts and micro-services, there is this excellent podcast by Eric Evans.