The DDD Way Towards Screaming Design — Part I: Strategic Patterns

In his book Clean Architecture: A Craftsman’s Guide to Software Structure and Design, Uncle Bob calls an architecture that tells the reader about the system, not the frameworks used in the system, a “Screaming Architecture.”
So, it makes sense to me to think of software design as screaming design when it speaks loudly and clearly about the problem domain. Generally, the most critical asset in designing a solution is acquiring knowledge about the issues we’re trying to solve, the process we want to automate or the difficulties we want to facilitate. So, to get close to the solution, we had to be already close to the problem.
In this blog, we’ll be talking about the way to get close to both problem and solution: the Domain-Driven Design (DDD) way towards a screaming design, the design that tells the reader about the business domain, not about the frameworks used.
What’s DDD?
The simplest definition that I have found was while reading the book Fundamentals of Software Architecture by Neal Ford & Mark Richards:
Domain-driven design (DDD) is a modeling technique that allows for organized decomposition of complex problem domains. — Neal Ford & Mark Richards. Fundamentals of Software Architecture. 2020.
Why to use DDD?
The goal of DDD is firstly to acquire knowledge about the problem to identify the solution. Then, we will agree on the various components of this solution to implement it.
How do we reach this goal?
This goal is achieved through the fundamental DDD patterns: strategic and tactical patterns. Strategic patterns answer the question, “Why are we building this software, and what are its components?”. On the other hand, tactical patterns give the answer to the question, “How are these components implemented?”

Let’s dive in the strategic patterns..
The strategic patterns deal with getting a big picture of the business domain, which includes decomposing it into business rules.
Strictly speaking, business rules are rules or procedures that make or save the business money.
— Uncle Bob, Clean Architecture: A Craftsman’s Guide to Software Structure and Design
In other words, business rules are the functional features that require development. Yet, there are different kinds of business rules. There are urgent and important ones. Still, other ones are not urgent but are important. Collecting and regrouping these rules meaningfully helps decompose the complexity of the business domain into subdomains: Core, Generic and Supporting subdomains.
The core sub-domain contains the business rules that deliver competitive advantage and highlight the difference between companies working in the same business domain. It embodies a highly complex and volatile business logic. Therefore, it has to be open to changes within the business logic, which may involve adding new requirements, updating old ones, or even removing some of them. It must then be carefully implemented in-house in order to allow these changes to occur efficiently without causing too many troubles in the whole software.
Completing the core sub-domain’s business rules requires other business rules that involve neither highly complex nor volatile logic. Instead, they just support the company’s business without invoking any competitive advantage since they are solving a very obvious problem. They are developed in-house and can be outsourced. Here, we’ve been talking about the supporting sub-domain. However, the generic sub-domain consists of business rules that relate to an already solved problem so it can be bought or adopted.
While distilling the business domain in search of sub-domains, we must speak the same language to understand each other. We should, therefore, use the same term to refer to a certain object, behaviour or field. In DDD’s terminology, it is called the ubiquitous language. Here, we’re evoking one of the indispensable ingredients to build a software solution: effective communication between the different project’s stakeholders, including developers, domain experts, business analysts, project managers, marketing managers, etc..
As software developers, we must ensure our assumptions align with the domain experts' knowledge. Alberto Brandolini, who is an all-around consultant in the Information Technology field, once said:
It’s not the domain experts knowledge that goes to production, it is the assumptions of the developers that go to production.
— Alberto Brandolini
He is a DDD expert who created EventStorming, a collaborative methodology involving all project stakeholders to share knowledge about the problem domain. He gathered them with colourful post-its and pens before a whiteboard to launch a knowledge-crunching session. I’ve already written a detailed blog about EventStorming, and you can find the link in the “Read Further” section at the end of this blog. Such methodologies help find boundaries to separate consistent business rules and regroup them by context. In DDD terminology, these groups are called Bounded Contexts, each containing consistent business rules.
How do we recognize consistent business rules?
Consistent business rules speak a consistent ubiquitous language. When we’re calling “one” concept using a different vocabulary, and we start to treat it from a different point of view, we may be talking about two different business responsibilities that require segregation of context. Also, consistent business rules often change for the same reason, so keeping them together is better.
Each bounded context embodies certain domain features to accomplish a single responsibility and can be packaged independently. In that way, our software will be sliced vertically and packaged by feature. Moreover, these vertical slices must communicate to process a specific business workflow. So, our bounded contexts have to collaborate; meanwhile, we should protect the consistency of the business rules. We should choose the type of communication that best suits the business requirements, no more, no less.
The way that bounded contexts should communicate also affects the way that teams should organize and collaborate. Two ways of communication are possible: cooperation or customer-supplier communication.
How do we cooperate in different bounded contexts ?
Cooperation is possible through partnership. In this type of relationship, teams are partners in solving issues that arise during the integration of bounded contexts; they must, therefore, synchronize frequently to detect blocking points in order to guarantee the integrity of the software.
Another way to cooperate between bounded contexts is to have a shared kernel. Teams create a shared model that has to be consistent across all of the bounded contexts using it. The use of this pattern should be justified by the cost of duplication, which is higher than the cost of coordination.
What about the Customer-Supplier relationship?
In the Customer-Supplier type of communication, we had two sides. The supplier side is called “upstream,” whereas the customers are known as “downstream.” The supplier is the one that provides a service to its customers. However, customers can interact differently with this service depending on the conformist, anti-corruption layer or open-host service pattern.
Conformist means that the downstream will conform to the upstream model. However, the downstream will not conform to the upstream model in the anti-corruption layer. It will instead customize it to suit its model via an anti-corruption layer to protect its model from corruption and irrelevant concepts that can damage the consistency of the bounded context. Another way to protect the downstream is to follow the open-host service pattern. In this pattern, the supplier will expose a service that conforms to its customers. In other words, the upstream may have different versions of a published language to conform to its corresponding downstream model.
After this long journey of getting the essential knowledge, decomposing the business domain into subdomains, delimiting contexts and drawing the relationships between them, we plot a context map. It’s a visual representation that gives insights, firstly, on the high-level design including our subdomains, bounded contexts as well as the model they will implement, secondly, on the communication patterns that must be used among the bounded contexts, and finally on the organization and collaboration of the teams.

By this, we’ve completed the talk about the strategic patterns. Teams are potentially ready to start discussing implementing these various components.
We also have reached the end of part 1 of this blog ^^.
In the next one, we’ll talk about the tactical patterns. As usual, I leave you with a little advice: The first step may be the hardest to take, but once you’ve taken it, everything follows, and you never regret it. The same goes for the DDD’s way. It may seem complicated to take, but once you do, you’ll enjoy it!
Read Further:
Event Storming — The Storm That Cleans Up The Mess!
Part II: Tactical Patterns — Tackling Business Logic