Integration Through the Data Store

One of the most commonly used techniques to integrate different parts of an application has always been to share the same data store, along with the same code base. This is usually known as a monolithic application, and it often ends up with a single data store that hosts the data related to all the concerns within the application.

Consider an e-commerce application. A shared data store would contain all concerns (Example: tables within a relational database) surrounding the catalog, billing, inventory, and so on. There's nothing wrong with this approach per se—for example, in small linear applications where the complexity is not too high. However, within complex Domains, some issues can arise. If you share data across many tables touching multiple application concerns, transactions will have a big impact on performance.

Another less technical problem that could develop is in regard to the Ubiquitous Language. The main advantage of the separation of Bounded Contexts is having a single Ubiquitous Language for each one. In doing so, models will be separated into their own Contexts. Mixing all models together within the same Context can lead to ambiguity and confusion.

Going back to the e-commerce system, imagine we want to introduce the concept of a t-shirt. Within the catalogue Context, a t-shirt would be a product with properties like color, size, material, and maybe some fancy pictures. In the inventory system, however, we don't really want to concern ourselves with these things. Here, a product has a different meaning, where we care about different properties like weight, location in the warehouse, or dimensions. Mixing both Contexts together will tangle concepts and complicate the design. In Domain-Driven Design terms, mixing concepts in this manner is what is called a Shared Kernel.

Shared Kernel
Designate some subset of the domain model that the teams agree to share. Of course this includes, along with this subset of the model, the subset of code or of the database design associated with that part of the model. This explicitly shared stuff has special status, and shouldn't be changed without consultation with the other team. Integrate a functional system frequently, but somewhat less often than the pace of CONTINUOUS INTEGRATION within the teams. At these integrations, run the tests of both teams.  Eric Evans - Domain-Driven Design: Tackling Complexity in the Heart of Software

We don't recommend using a Shared Kernel, as multiple teams can collide within the development of it, which not only results in maintenance issues but also becomes a point of friction. However, if you opt to use a Shared Kernel, changes should be agreed upon beforehand and between all parties involved. Conceptually, this approach has other problems, such as people seeing it as a bag to place stuff that doesn't belong anywhere else, and this grows indefinitely. A better way of dealing with the ever-growing complexity of the monolith is to break it up in different autonomous pieces, such as communicating through REST, RPC, or messaging systems. This requires drawing clear boundaries, with each Context likely ending up with its own Infrastructure—data stores, servers, messaging middleware, and so on — and even its own team.

As you might imagine, this could lead to some degree of duplication, but that's a tradeoff that we're willing to make in order to reduce complexity. In Domain-Driven Design, we call these independent pieces Bounded Contexts.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset