Este post también está disponible en español.

Posts in this series:

In the previous post of this series we saw how to decompose a complex domain into less complex subdomains.

Each subdomain has its own model, therefore we are going to have many models coexisting at the same time.

If we only had a single model, the concepts of a business area could be confused with similar concepts from other areas and this would increase the complexity and coupling. Domain-Driven Design proposes separating a large system into many models protecting the integrity of each one so that concepts remain isolated, consistent and protected. This is achieved by encapsulating each model into a Bounded Context.

Ideally we will have a Bounded Context per subdomain but sometimes this is not the case. Sometimes a subdomain can be have multiple Bounded Contexts or a Bounded Context spans into more than one subdomain.

Solution space vs problem space

Subdomains are in the problem space, of the domain. They emerge from analyzing and breaking down the problem.

On the other hand, Bounded Contexts are in the solution space, the software implementations.

Bounded Contexts are the subsystems that we implement (For example: a billing system, an inventory system, etc.)

These subsystems generally interact with each other in order to provide the overall functionality of the entire system. They are usually integrated through APIs or other mechanisms that we’ll see later.

A Bounded Context can be composed of one or more software artifacts (applications, services, etc.)

One team per Bounded Context

Each Bounded Context is developed and managed by a single team.

One team per Bounded Context

It would be complex for several teams to share the same model and codebase. They should coordinate changes and releases to production.

The collaboration and coordination of multiple teams to develop and deploy features generates a lot of unnecessary inefficiency.

With one team per Bounded Context, each one iterates their own model, deploys features and publishes them to production independently.

Eliminate ambiguity

Different areas of the company often use similar but different terms, generating ambiguity.

In a company that sells tickets for shows, there will surely be areas that refer to a ticket as the document that allow us to be admitted in an event, but a customer support area could use the concept of a ticket as a support issue to be addressed. Both terms mean different things even though they have the same name.

Each Bounded Context has its own ubiquitous language that removes these ambiguities.

A Bounded Context establishes a linguistic and contextual boundary. In the support Bounded Context a ticket means an issue, in the sales context it means a product sold.

Ambiguity

If, for example, our domain is a book publishing company, surely the concept of a book will be present in many subdomains. But it does not mean exactly the same thing.

During the writing stage, the book will likely have drafts, an assigned editor and comments along with a final draft.

Graphic designers create cover art, layouts, and images for the press.

Marketing doesn’t need all the graphics, just the cover art and high-level descriptions.

For shipping, we’ll surely need to know the location in the inventory, the available stock, the dimensions and the weight.

If we try to model all these features in a single Book object, we would surely end up with a complex model.

A better alternative is to divide our single model into several models (one for each subdomain addressing a specific problem). Each model will have its own Book object focused on meeting the specific needs of each context.

In the case of an ecommerce, we’ll have a similar problem with the concept of a Product:

  • For the catalog a product has images, data sheet and description.
  • For inventory it has stock.
  • For marketing a product has promotions and discounts.

Modeling a single Product class for all these cases would cause us many problems and introduce a lot of complexity.

Product ambiguity

By decomposing the solution into several Bounded Contexts, we’ll have many smaller subsystems, each with its own Product class. The complexity would be reduced overall and it would be easier to manage.

Product in many contexts

Implementation

A bounded context owns a vertical slice of functionality from the presentation to the data storage layer. Each one can be developed and deployed independently without affecting the others.

Vertical slices

Sometimes it’s common to share the UI between many contexts. In these cases, a composite UI is usually used (as is the case, for example, with Amazon)

Composite UI

Next post

In the next post we will see how to integrate several Bounded Contexts to compose a system, both at the implementation and political levels.