Tensions when Designing Evolvable Bounded Contexts

Bounded Contexts and their interfaces are governed by fundamental tensions that affect our design

By Mathias Verraes
Published on 09 April 2021



(This is a small snapshot from a longer conversation I’m having with Rebecca Wirfs-Brock about Bounded Contexts. It’s very incomplete but I’m posting it anybody who get some value from it in its present form.)

Context

  • A Bounded Context is an “understandability boundary”, a boundary around a model and its language. You can understand the model and the language in isolation, without having to understand other Bounded Contexts.
  • An Interface is the set of contracts or message types or APIs between Bounded Contexts. They translate from one model and language to another.
  • A Bounded Context or Interface is evolvable if we are able to make frequent, safe, and cheap changes to it.

Tensions

When designing evolvable Bounded Contexts (BCs), there are fundamental tensions that affect our design.

  1. A BC is evolvable on the inside if it is small and understandable and has a small stable Interface.
  2. A system of BCs is evolvable (adding, removing, reconfiguring BCs) if the Interfaces are small and understandable.
  3. The tension between 1 and 2 is that choosing many small BCs implies having larger Interfaces, but choosing many small Interfaces implies having larger BCs.
  4. The Interfaces themselves are more evolvable if they integrate fewer BCs, and less evolvable if they integrate more BCs.
  5. The consequence of 2 and 4 is that a small evolvable Interface makes adding BCs easier, but becomes less evolvable in the process.
  6. It’s easier for a BC to offer a single generic shared Interface, than many specialised Interfaces for each consumer. Having many specialised Interfaces is harder to maintain when the BC changes.
  7. It’s easier for a BC to consume a specialised Interface, adapted to that BC. Generic interfaces are bloated because they support other consumers, and therefore require more integration work.
  8. Trading off 6 and 7 involves finding a small set of semi-specialised Interfaces, that are shared between some consumers with similar needs.
  9. Coordination between teams (which is in fact coordination of understanding, aka sharing models and language) is expensive, which is one of the reasons we have BCs to begin with.
  10. Achieving 8. requires more coordination between more teams than either a single generic Interface or individual specialised Interface.

There are no solutions or hard rules to make these trade-offs. Instead, you need to use heuristics for making the trade-offs, and heuristics for knowing when to choose different trade-offs than the ones you originally made.