Context Map

6 min read

We already know that BCs are not like silos. It’s very rare for Contexts not to have any dependencies or relationships with other ones. When it comes to decide how we want to make them go together, we have few good options available. These are called Integration Patterns (IP) and their usage can be graphically documented using Context Maps (CM). In their simplest form they look like this:

What Integration Patters Are Available?

There are seven of them, and they propose different ways to deal with following problems:

It’s important for you to know them by heart. If wrong one is used it may cause the whole project to stuck in a mud. That’s because every Integration Pattern enforces its own rules and ways for Contexts (teams) to cooperate. Can you anticipate what will happen to the patient, who was given cold medicine for a shot wound? His bleeding won’t stop and in consequence he will die. The same may happen to the project. Bad decisions and lack of knowledge may cause the business to bleed slowly and finally patient will pass away. It’s not what we want, that’s for sure.

Partnership

This pattern lays emphasis on close cooperation between teams, which must be extraordinary. Everything must be well planned, talked over and documented. Teams take care of each other, their common goal is to avoid pitfalls and destructive activities. Everyone involved must do their best to keep the cooperation flame burning.

Shared Kernel

As its name suggests, this pattern is about a shared codebase, which is called a Kernel. It is shared, so any team may provide changes to the Context, but they must remember to communicate their intentions first. When updates goes unnoticed, it may cause some serious trouble for both teams. Mind that this integration should be as tiny as possible, so it doesn’t become unmanageable monster.

Customer - Supplier

Situation here is similar to stream-wise relationships which I have already mentioned earlier: Upstream and Downstream. What makes this pattern different is how roles are defined for each party. Upstream is equivalent of the Supplier what makes it a serving team. Downstream crew, on the other hand, plays role of a Customer, the one to be served. Both squads are more or less independent, but it’s up to Supplier to take care of its Consumer’s needs.

Conformist

In this scenario, Downstream party puts a conformist mask on. Whatever crazy Upstream does, it will be reflected on the other end. No questions, no debates, no arguments. It seems quite appealing, don’t you think? :)

AntiCorruption Layer

So here’s the story. Upstream does not give a heck about Downstream. Yes, there are companies where this relation exist and is doing better every day. Lack of communication and support from Upstream, actually makes Downstream party angry, frustrated and burned-out. They also have this manner to release untested builds as production-ready, what constantly drives crazy almost everyone in the company. Team B decided that the best IP in this case would be AntiCorruptionLayer (ACL). Thanks to this layer, Downstream avoids being corrupted by Models from Upstream, they communicate using ACL instead. Downstream is able to operate normally even if some garbage was streamed down. Please note, ACL is still a subject for change when it comes to update Upstream Models.

Open Host Service

Kind of different from others. How? First, it doesn’t care about streams, teams or relationships. It has one, clearly defined agenda, which is commonly known by every other system. Great example of such “Integration” would be REST API or GraphQL. Actually, every protocol or popular service can be used as an interface here.

Published Language

If it’s not the most liberal one, then I have no idea what liberal means. It doesn’t care how you will provide the Language. Is it going to be a stream or a file? Is the network involved? Maybe there is a file on your local hard drive? Typing its content to the console program input is also an option. The only thing that matters, is the Language itself, not the way how it was loaded into a program.

Separate Ways

Well…, this one is like a bad marriage. At the beginning, integration seemed like a good idea, but as the time was passing by, so were their relationship. Then, the day has come. There was no point trying to keep them together, and they have already made up their minds. We need to be free - they agreed. We must go separate ways. Bye.

Completed Context Map

Now you know all seven ways to integrate Bounded Contexts. It’s a good moment to update our Context Map.

Between Acceptance and Storage Shared Kernel pattern was used. That’s because during the acceptance phase a new product is added to database. It has its metadata (IBAN, Title, Author, etc.) available, and it turns to be a master record for this particular volume. Storage is using shared code to fetch records with accepted titles.

When it comes to Stores, they basically use data persisted in a Storage (Warehouse) Context. Together with price and promotions they are reflection of Domain Models used in Storage. In this scenario, Conformist was a way to go. Stores can adopt down-streamed Model almost one to one.

The last part is Reviews which are available at Online Store. These opinions are managed by the external service. Reviews can be added in Online Store Context, that’s why it provides all required functions for its Downstream counterpart. Customer - Supplier pattern was the best choice.

Summary

Do you like what you’ve learned? I hope so :) As you can see, Strategic phase of a Domain-Driven Design is a crucial process. Without it properly conducted, without deep Domain knowledge, you probably won’t succeed with this approach. This is the best time to get familiar with all tricks, gotchas, quirks and stupid things waiting out there for you, ready to kick you in your six. Every good carpenter knows, that it’s better to measure twice and build once, than measure once and build twice. Be like a carpenter and always be sure about results of your job. Knowledge plus good plan equals success.