Bounded Contexts / Ubiquitous Language
My new book, Data Model Storytelling,[i] contains a section describing some of the most significant challenges data modelers and other Data professionals face. One of these challenges is the increasing popularity of an approach to application development called Domain-Driven Development (DDD).
Like most of its predecessors, including Agile development and Extreme Programming (XP), Domain-Driven Development is characterized by two things: 1) An unwillingness to look at the discipline from anything other than an application developer’s point of view and 2) An unwillingness to consider the Data Management aspects of application development, or to view Data Management professionals as affected Stakeholders in the development process.
As with Agile and XP, this leaves Data professionals confused and wondering how they can contribute effectively and meaningfully to these projects. In this series of articles, I’d like to explore some of the data-related implications of DDD and draw on the lessons I’ve learned from supporting Agile software development projects for nearly 20 years and apply some of these same principles to this new approach.[ii]
The overall objective of Domain-Driven Development is to confine both the application and the database (or data persistence store) to a carefully defined subset of a business domain called a “Bounded Context.” In other words, a database will no longer support multiple applications, or even necessarily a single application. Instead, a database (or persistence store) will support a set of services defined within a particular Bounded Context. Each Bounded Context has its own persistence store and can communicate and share data with other Bounded Contexts using services (which are often called “microservices”).
As with Agile, XP and similar approaches, the principal justification for this choice of architecture is speed of application development. By encapsulating both the application logic and the database schema within a particular subdomain, each application can be developed and maintained by separate teams and deployed as often as the team wishes without having to consult or interact with other teams (e.g., the database team). It is further argued that this approach helps keep business logic from “leaking” into the database and replaces database transactions with application messaging.
A secondary argument for the domain-driven approach, according to Martin Fowler,[iii] is that the business’s understanding of the data (and the language it uses to express that understanding) varies from one business domain to another. This is what makes it difficult to create an enterprise-level data model since, for example, the Sales Department’s understanding of terms like “Product” and “Customer” may be different from that of, say, the Service Department.
What defines a Bounded Context is something called a “Ubiquitous Language.” In other words, within the Bounded Context, all business terms have an agreed-upon meaning, and are understood by all the Stakeholders participating in the Bounded Context. The Ubiquitous Language is what the Stakeholders use to discuss business requirements, application requirements, business rules, data meanings and so on.
Therefore, for the purposes of Domain-Driven Development, we can say that a “domain” represents an area of the business in which language (including data-related language) has the same meaning and is similarly understood. A “subdomain” is a part of the domain supported by a common set of data and services.
So far, so good (or bad, depending on your point of view). However, there are some points that need to be raised and discussed about this approach. Let’s start with the ones pertaining to data architecture and data modeling:
- None of the books on DDD even mention data architecture or data modeling as a part of the development process. Eric Evans’ text relegates anything having to do with data to the “Infrastructure” Layer of the application, rather than the “Domain” or “Model” Layer.[iv] But this is wrong, for three reasons: First, as I will explain in a moment, the data model is absolutely crucial to the development of the Ubiquitous Language used to define the Bounded Context (i.e., the definition of the business domain must include data names, definitions and business rules). Second, as Evans himself points out, the Domain Layer is where the models that drive the application development live.[v] Third, as Evans also notes, the Domain Layer is where the business rules are defined![vi]
- Application developers don’t necessarily have knowledge of a business domain or the business processes it supports. That’s why books on application development recommend including “Domain Experts” from the business on the dev team. But there is never any acknowledgement that Data professionals in an organization also have this domain knowledge and can contribute meaningfully to the development of the Ubiquitous Language and Bounded Context. In fact, as I will show, Data professionals can help surface project requirements that functional analysts miss!
- Application developers also don’t often have a broad organizational view. They are recognized and rewarded for a single-minded focus on pushing application functionality out the door as quickly as possible. With that sort of focus, larger organizational goals (such as a sustainable application and data architecture, or high-quality, reusable organizational data) can be lost.
- It needs to be acknowledged that, regardless of the methodology being used, data models contribute value to projects in many different ways: They help prevent data from being persisted or represented in ways that violate the business’s understanding of the data, they bring project Stakeholders together to discuss and understand the business domain, they help surface business requirements not covered in the functional use cases, and they capture and document agreements and assumptions being made.
- Data models are also an essential part of Model-Driven Development (MDD). In MDD, models are used not only to understand and discuss a problem, and capture knowledge about a problem, but they are also used to implement at least part of the solution to a problem. Data models capture essential information about the Data aspects of the business domain and the problem being solved and can be used to generate both data schemas and data-related business rules and constraints.[vii]
- Also, as we will see, data models are essential for determining what sort of data we are working with, and where that data should reside. Some data is subdomain-specific and can reside in a subdomain persistence store. Other data should be defined at a domain level and put in a canonical data store, perhaps on the ESB Hub to support common domain services. Data that is Master data should be defined at the organization level and stored in an MDM repository.
Let’s look at a specific example that will help clarify some of the above-mentioned points:
Bounded Context Example, from Martin Fowler.
This application consists of two Bounded Contexts, one for Sales and one for Support, which communicate with each other via services. Each of the contexts contains a Customer entity and a Product entity. In DDD, it is perfectly OK for these entities to have the same name, but entirely different meanings. But, shouldn’t we at least ask the question: Are these the same things, or different things?
In the case of the Customer entity, it may very well be that these are both the same thing. The same Customer who buys a Product is probably also the same Customer who needs support for that Product. But this isn’t always necessarily the case. In the Truck market, for example, an owner-operator may sell a truck to another owner-operator and, in many cases, the warranties on the truck will transfer to the new owner. So, these are not the same person, but they are at least the same class of Customer, with the same attributes. But it’s also possible for a fleet owner to sell some of its used trucks to owner-operators. In this case, Customer becomes a subtype, with Fleet Owners and Owner-Operators having different attributes.
In the case of the Product entity, however, it’s obvious that these are not the same thing. When I order a new printer online, I don’t order a specific printer; I order a particular brand and model of printer and they send me whatever they have on the shelf. But when I need support, I register a particular instance of that printer with a particular serial number. In other words, “Product” in a Sales context is actually a Product Model (identified by a Model Number), while “Product” in a Support context is a specific instance of a Product Model with a uniquely identifiable Serial Number. Both of these entities have entirely different attributes!
It’s also obvious that Product Model is a Master Data entity and needs to be persisted in an MDM repository or some other Enterprise-level data store and should not be persisted at the subdomain level. This may also be true of the Customer entity if the organization is doing Customer MDM.
In Domain-Driven Development, not only is it OK for data entities in different subdomains to have the same names but different meanings, it’s also OK for data entities in different subdomains that have the same meaning to have different attributes, and those attributes might have different attribute names. This is because these “persistence stores” are intended only to provide support for the set of services defined within the subdomain. Entities don’t have to be fully defined within a subdomain. But this is problematic, for a number of reasons. For one thing, it makes it harder for developers working within one Bounded Context to create services that communicate with a different Bounded Context, if similar data elements aren’t similarly named and defined. It makes sharing knowledge with team members across subdomain boundaries more difficult. And, as I will explain in a subsequent article, persisting data at the wrong level can cause an immense amount of hardship for a project!
Not having a data model to support the capture and sharing of knowledge and understanding about a business domain makes it much harder to develop a meaningful Ubiquitous Language and properly define the Bounded Contexts of an application. Here’s an example: My most recent project was a Product Registration and Warranty/Warranty Claims application for our company. I began by bringing together experts from the business unit that issues Warranty contracts. I walked them through the business process and created a first-cut Warranty data model. Then I brought in the people who process warranty claims and showed them the data model. They said, “That’s not how warranties work!”
Now a lot of developers would have said, “Well, these must be two separate Bounded Contexts, with different business definitions of the term ‘Warranty’, so we’ll create two separate subdomains.” But I wasn’t satisfied that this was actually the case. So, I brought both groups of people into the room with the data model and we started to hash through the apparent discrepancies. What happened is that we were able to resolve the misunderstandings and arrive at a data model that encompassed the entire scope of the Warranty domain. Moreover, in the process of resolving the issues, we also surfaced a number of business requirements that had not previously been identified by the functional use cases for the application! We ended up with a data model that more adequately met the needs of the entire project team and we also identified additional requirements that would have otherwise surfaced midway through the project and cost us time and money to address.
One more comment about data models: As I explain in Data Model Storytelling, every data model tells a story, and it has to be the correct story. It has to tell a true story about how the organization currently works, and it has to tell a good story about how we’re going to get from where we are now to where we want to be (and how we are going to solve the current business problem). Eric Evans touches on this in a section of his book entitled “Modeling Out Loud”.[viii] It’s important that a data model communicate a clear and correct story, in business terms, at the correct level of detail (i.e., not too abstract to immediately understand), and free of jargon. As Evans states, “If domain experts don’t understand the model, there is something wrong with the model.”[ix] It’s important to understand that a data model can be semantically correct, but still tell the wrong story. That’s why it’s important to start with a high-level Conceptual model first, so the domain experts and project stakeholders can make sure the correct story is being told before too much work is put into the model.
Data models contribute value to a project by enabling people to ask questions and have discussions about important business requirements, including data nomenclature and meanings, business rules and constraints, and the organizational level at which data should be defined and managed. Without data models, many of these questions would never be asked (or, at least, not until it was too late!).
To be continued…
[i] Burns, Larry. Data Model Storytelling (New Jersey: Technics Publications LLC, 2021.
[ii] Data Model Storytelling contains an entire section which explains my approach to supporting Agile software development and Agile BI.
[iii] Fowler, Martin. “Bounded Context”. January 15, 2014. https://martinfowler.com/bliki/BoundedContext.html.
[iv] Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software (Addison-Wesley, 2004), p. 70.
[v] Ibid, p. 75.
[vi] Ibid, p. 71.
[vii] Ibid, pp. 12-13.
[viii] Ibid, pp. 30-32.
[ix] Ibid, p. 33.