Skip to content

Context Mapping

Context Maps describe the contact between bounded contexts and teams with a collection of patterns. There are nine context map patterns and three different team relationships.

In large and complex applications, multiple models in context collaborate to fulfil the requirements and behaviours of a system. A single team may not own all the various sub components of a system, some will be existing legacy code that is the responsibility of a different team, and other components will be provided by third parties that will have no knowledge of the clients that will consume its functionality. Teams that don’t have a good understanding of the different contexts within a system, and their relationships to one another, run the risk of compromising the models at play when integrating bounded contexts.

9 Context Mapping Patterns

These patterns define how Bounded Contexts interact:

Partnership: Two contexts collaborate closely and evolve together.

Shared Kernel: Two contexts share a subset of the domain model.

Customer/Supplier: One context (supplier) provides data or services to another (customer).

Conformist: One context conforms to the model of another, often due to lack of control.

Anticorruption Layer (ACL): A protective layer that translates between two contexts to prevent corruption.

Open Host Service (OHS): A context provides a well-defined API for others to interact with.

Published Language: A standardized format or language for communication between contexts.

Separate Ways: Contexts operate independently with no integration.

Big Ball of Mud: A chaotic, poorly defined relationship between contexts (to be avoided).

3 Team Relationships

These describe how teams interact when working with Bounded Contexts:

Mutually Dependent: Two teams or bounded contexts are mutually dependent when their software artifacts or systems need to be delivered together to be successful and work. You will often see a close, reciprocal link between data, functionality and capabilities of these teams.

Upstream/Downstream: Actions of an upstream team will have an effect on the downstream team, but actions of the downstream do not have a significant impact on the upstream team.

Free: A Bounded Context or a team that works in it is free if changes in other Bounded Contexts do not influence its success or failure. There is, therefore, no organizational or technical link of any kind between these teams.

Example of Context Mapping in Action

An example of a context map:

The figure above illustrates a context map. You can see that there is an Anti-Corruption Layer in place which protects the HR context from the recruitment context. This is because the recruitment context is a third party which is prone to other forces which shouldn’t affect our prime contexts. We will dig deeper into ACL (Anti Corruption Layer) further down.

It is extremely important that context maps reflect reality, showing the code in the present state rather than an ideal future state. Context maps doesn’t need to show the detail of a model; instead, they must demonstrate the integration points and the flow of data between bounded contexts. We still haven’t illustrated the relationship status on the context map other than connection points, so learning more about how we can illustrate the flow of relationship is the next topic.

Upstream/Downstream relationship

A very important factor in DDD context maps, is the direction of the relationship between two contexts. DDD uses the terms upstream or downstream: an upstream context will influence the downstream counterpart while the opposite might not be true. These are often shortened to the letter d and u respectively.

This might apply to code (libraries depending on one another) but also on less technical factors such as schedule or responsiveness to external requests. In the example below, you have a context map which illustrates a Personal Finance Management Application that talks to an online banking service through an API. So, in this case, the PFM application is the downstream, and the online banking service is the up streamer

Elaborating on a Context Map

PFM application is interacting with the online banking service through an API, we need some kind of protection against changes coming from the upstream context. This will help us to preserve the integrity of the banking context. The most common practice to do so, is to implement something called an Anti Corruption Layer (ACL). This puts up a barrier at the tip of the context that the stream has to go through before getting accepted into our PFM context. In the ACL, an explicit translation is happening at the code level between the two contexts. An example could be to transform the incoming object from the legacy model to the domain object in your main application’s model.

This works as a place to manage all the subtle differences between the models on both ends. Microsoft has a pretty well defined guide on ACL.

There is also going to be other contexts in a bigger picture within the organization, that are not external. These contexts might be maintained by other people and are subject to different forces. We might need to interact with these as well. If Banking and Expense tracking were to be maintained by different teams, they’re likely to be in a partnership relation: they’re both developed towards a common goal (and upstream-downstream doesn’t make much sense since they’re on the same level). If Web User Profiling is achieved with an external module, we’re probably going to use it “as-is”, meaning that we’re downstream and Conformist, towards Web User Profiling.

Cheat Sheet

Here is a cheat sheet containing brief descriptions of the context mapping patterns:

Reference

  • "Context Map Cheat Sheet" by https://github.com/ddd-crew/context-mapping
  • "Domain Driven Design Quickly" by Abel Avram and with Floyd Marinescu