Every enterprise system eventually runs into the same problem. The word “customer” means one thing in billing, another in support, and something else again in shipping. Teams often try to fix this with a single canonical model. The result is usually a bloated entity that serves no one well and that everyone is afraid to change.

Domain-Driven Design takes a different approach. Rather than forcing agreement, it draws boundaries. A bounded context is a region where a model has one consistent meaning. Inside the boundary, language is precise. Across it, translation is required.

Boundaries raise a new question: how do these contexts talk to each other? Integration is where many architectures quietly fail. This article examines the integration patterns Eric Evans catalogued, and how to choose among them deliberately rather than by accident.

Context Mapping: Seeing the System as It Really Is

A context map is a document, often just a diagram, that shows every bounded context in a system and the relationships between them. It sounds modest. In practice, it is one of the most revealing artifacts a team can produce, because it forces implicit assumptions into the open.

The key insight is that a context map describes the system as it is, not as anyone wishes it were. If the order service reaches directly into the inventory database, the map shows that. If two teams share a library that neither fully owns, the map shows that too. An idealised map defeats the purpose. Its value lies in honest diagnosis.

Each relationship on the map has two dimensions. The first is technical: how data flows, what format it takes, and who translates it. The second is organisational: which team has influence over the other, who must adapt when an interface changes, and whose priorities win. These dimensions cannot be separated. Conway’s Law ensures that the communication structures between teams will show up in the integration between their systems.

Mapping also exposes the “big ball of mud”: areas where boundaries have dissolved and models have bled into one another. Naming these regions explicitly is the first step toward containing them. A team that knows where the mud is can build walls around it instead of tracking it through every new feature.

Takeaway

A context map is a diagnosis, not a blueprint. You cannot choose the right integration strategy until you honestly see the relationships, both technical and political, that already exist.

Partnership Patterns: How Team Relationships Shape Integration

The relationship between two contexts is shaped by the relationship between the teams that own them. Evans identified several recurring arrangements. Each reflects a different balance of power and a different cost of coordination.

With a shared kernel, two teams agree to share a small subset of the domain model, such as a set of value objects or a common event schema. Neither team can change it without consulting the other. This reduces duplication and translation, but it couples release cycles. A shared kernel works only when it stays small and the teams communicate closely. Once it grows, it becomes a bottleneck that both teams resent.

In a customer-supplier relationship, an upstream team provides data or services that a downstream team consumes. What defines this pattern is that the downstream team’s needs genuinely influence the upstream roadmap. Requirements are negotiated, and acceptance tests written by the customer can protect the contract. The arrangement depends on the upstream team actually caring, which requires organisational incentives rather than goodwill alone.

The conformist pattern applies when the upstream team has no motivation to accommodate downstream needs. Typical examples are a large platform team, a vendor, or a legacy system no one will touch. In these cases the downstream team may simply adopt the upstream model wholesale. This is not a failure. It can be a pragmatic choice that eliminates translation cost. The risk is that a poor upstream model now dictates the shape of your own domain logic, and its compromises become yours.

Takeaway

Integration patterns are really descriptions of team relationships. Before choosing one, ask who has leverage, who bears the cost of change, and whether that balance is likely to hold.

Protective Patterns: Anti-Corruption Layers and Open Host Services

Sometimes conforming costs too much. When an upstream model is confusing, unstable, or simply wrong for your domain, letting it leak into your code means every downstream decision inherits its flaws. This is where protective patterns earn their place.

An anti-corruption layer is a translation boundary owned by the downstream context. It speaks the upstream model on one side and your own model on the other, typically through adapters, facades, and translators. The rest of your code never sees the foreign concepts. Consider a legacy mainframe whose “account” entity mixes together customers, contracts, and billing addresses. An anti-corruption layer lets your new system work with clean, distinct concepts while the mess stays quarantined.

The cost is real. An anti-corruption layer is code that must be written, tested, and maintained, and it can grow into a significant subsystem in its own right. It is justified when the upstream model differs meaningfully from yours, when the upstream is likely to change, or when your domain is core to the business and deserves protection.

The open host service tackles the problem from the opposite side. When an upstream context serves many consumers, building a custom translation for each one becomes unsustainable. Instead, the upstream publishes a well-defined protocol, often paired with a published language such as a documented schema or standard format, that any consumer can use. The internal model stays free to evolve while the public interface remains stable. Many modern API strategies are open host services in practice, whether or not teams use that name.

Takeaway

Protection is a deliberate investment, not a default. Spend translation effort where your model matters most, and let upstream providers absorb that cost when they serve many consumers.

No single integration pattern is correct. Each one trades autonomy against coordination, and translation cost against model purity. The real mistake is not picking the wrong pattern. It is letting patterns emerge by accident.

Start by mapping what exists. Identify where teams have leverage and where they do not. Protect your core domain with anti-corruption layers, and conform where the model is generic and good enough. Keep shared kernels small, and publish stable interfaces when many consumers depend on you.

Revisit the map as the organisation changes. Reorganisations, new vendors, and shifting priorities all alter team relationships. An integration strategy that fit well last year may be quietly costing you today.