Is Domain-Driven Design really worth it?
Updated: Mar 27, 2022
If you're reading this blog, you're possibly confused and also have a lot of questions, such as:
Is DDD worth it?
Is DDD philosophy against the YAGNI principle?
Is DDD overrated?
Should I bother about DDD?
Is DDD a silver bullet and can it be applied to all projects?
Is DDD a waste of effort?
I'll try to address the above questions in this blog, but first, let me tell you a short rejection tale that inspired me to learn DDD (Domain-Driven Design).
Interviewer: How do you identify a Microservice ?
Me: Microservice should be small in size and should do only one thing !!!
Interviewer: How small ? What's the right size ?
Me: I answered blah.. blah...
Interviewer: Do you involve domain experts in this process ?
After 40 mins of massacre 🤯🤯, the Interviewer said these golden words to me
You can leave for the day, HR will get back to you !!!
After getting home, I spent about 30 minutes googling the same question and came across the phrases "Bounded Context" and "DDD" on various sites.
Before we go into Bounded Context, let's first figure out what DDD is and why we need it?
Microservices usage is widely spread. It is a modular strategy that functionally decomposes an application into a collection of fine-grained services. When designing large-scale, sophisticated services, microservices are critical. Most of our microservices are now too complicated for a single person or team to manage, comprehend, and implement. A team of developers must break applications into modules that can be built and understood.
To understand microservices better, let us take an example of simple E-commerce Microservices architecture
The above image shows microservices that are part of an E-commerce application and each microservice has an impermeable boundary(Bounded Context) that is difficult to violate. Also, Microservices must have high cohesion and low coupling to avoid interdependency between microservices and scale independently. Identifying microservices is not as easy as it sounds because you need to have a solid understanding of the domain, transactional boundaries, and a single well-defined purpose.
Thankfully, DDD helps you to solve this problem of identifying microservices
Analyze the domain: analyze the business domain to understand the application's functional requirements. Eg: Event Storming session
Define Bounded Contexts: define the bounded contexts of the domain. Each bounded context contains a domain model that may represent a particular subdomain of the larger application. We will cover this in a while.
Define entities, aggregates, and services: Within a bounded context, apply tactical DDD patterns to define entities, aggregates, and domain services.
Identify Microservices: Following the above steps will get the desired result
First step, We need to analyze the domain !!! But how ????
1. Analyze the Domain:
DDD stands for Domain-Driven Design. It is neither technology nor a tool; rather, it is a software design methodology that focuses on modeling software to fit a domain based on input from domain experts. Eric Evans introduced this concept DDD in his book "Domain-driven design," often known as the "Bluebook."
In layman's terms, DDD is a design methodology that enables us to create better and more maintainable software that is domain-focused.
Often people try to jump directly into implementation details even before thinking about the domain (Problem Statement) and that's exactly what DDD focuses on, the domain. DDD is a process that involves Domain experts (stakeholders) and the engineering team to discuss in a common language and understand more about the domain and design the system better.
Why domain is so important for DDD other than having the word <domain> as the first word. Let's figure it out!!
Domain is an area of knowledge or activity
For example, E-commerce, Banking, Mobility, etc. Every Domain contains a set of activities, processes and it consists of experts who are responsible for the execution of these activities and we call them "Domain Experts".
Let's take E-commerce as an example, It contains many activities and Processes like
The domain is very big to understand as a whole. Instead, it is better to break the domain into smaller pieces called subdomains.
Subdomains are categorized into three different types:
Core Subdomain: Where all main business flows and models are understood and defined. For instance, in an E-commerce application, the main activities we need to support are offer generation, catalog management, etc.
Supporting Subdomain: All the activities that are built to support the core subdomain. With regards to the previous example, Shipping, and Backoffice subdomains are supporting subdomains for the core subdomain.
Generic Subdomain: Activities that are common across multiple domains but they are not part of the core domain. For example Analytics, Payment. These subdomains can be part of multiple other domains and we can generically build these subdomains to support other domains.
It would be practically difficult for someone to know the entire domain, which is where domain experts come in, and these domain experts are those who are knowledgeable about a certain subdomain.
To better comprehend the domain, we require the assistance of domain experts to model the domain. The Event Storming Activity assists the Engineering team in better understanding the model by including domain experts.
During an event storming session, business experts may use business jargon (terms) and the engineering team may use technical jargon. This will require both sides to translate and understand the meaning, and there is a high chance of miscommunication or loss in translation. In the DDD world, domain and technical experts should use the same language, which is called "ubiquitous language." Software that is built on top of this language is easy to understand because it reflects business terminology in the code.
2. Identifying Bounded Context:
It's almost impossible to create one model that represents the whole domain. Even if you can, that makes the system so complex and difficult to understand and translate into code. DDD deals with these problems by splitting the domain into independent parts called bounded contexts.
A bounded context defines the limit of applicability for ubiquitous language. Since domains and subdomains often become big, it is difficult to model them as one single model. Instead of a single large model for the domain, you have many smaller ones that are well-defined and have specific boundaries for what they are meant to encapsulate. Also, the meaning of words that are used in a specific bounded context will be different in another bounded context.
As Anders gill explained in his blog, the meaning of a specific word varies from one bounded context to another context. The word Serve means something different in a restaurant context compared to a Tennis related context. Set and Pour are other examples as well.
If you take the Ecommerce domain as an example, we can identify multiple bounded contexts and the relation between them (context maps) as shown below. "Item" is a common term that can be used in every bounded context and it has a different meaning in every bounded context. So instead of keeping it as a shared or generic model, it is better to treat it separately.
The main characteristics of bounded contexts:
Each bounded context should have its own domain model.
Each bounded context uses its own ubiquitous language.
A domain model built for a bounded context is only suitable within its boundaries.
We almost reached the end of this article, I hope you got some idea on strategic DDD. Let's go to the main topic of the article?
Strategic DDD mainly talks about analyzing a domain (bounded context, domain, subdomains, context mapping, etc.) and Tactical DDD talks about implementation using DDD jargons like (Entity, Aggregate, services, etc.)
Is DDD worth it?
I feel we cannot say something good or bad without analyzing its benefits and drawbacks.
Flexibility: When a project is developed using DDD, it is easier to evolve and change things like business processes, implementations, or technological stacks, which gives us a better time to market.
Code is organized: DDD can be used in conjunction with Hexagonal architecture, which requires our code to adhere to a predefined structure, allowing developers to test the relevant levels and adjust the code without fear of breaking anything.
You can be a Product Minded Engineer: Product-minded engineers are developers that have a strong passion for their product. During the domain analysis phase, you learn more about the product by speaking with stakeholders (product owners); this will help you make crucial decisions when designing the product. In my perspective, a good product-minded engineer can take the product to the next level, and they are the people who can easily transition from individual contributor to manager.
Domain logic is in one place: All the business logic(domain layer) would be separated from the infrastructure and the application layer if you are following Hexagonal architecture. so you can focus mainly on the domain layer and test it thoroughly with unit and component tests.
It is not a silver bullet: DDD only works in complex domains, which are difficult not only in terms of technology but also in terms of business. Projects that are more technical and involve less business interaction, such as developing a generic logging system or platform libraries, are not a suitable match for DDD.
The learning curve is steep: You need to have a solid understanding of DDD both strategic and tactical DDD. This is why any team that wants to build software based on DDD should possess good knowledge in this practice.
Time and effort: Most of your time will go into understanding the domain and talking to domain experts but sometimes this is really worth understanding more about the domain so that the engineering team can design the system better.
It is very easy to do wrong: As I mentioned before DDD is a philosophy and not a technology so it is very easy to do wrong. You should be agile to refactor your design till you get a near-perfect domain model.
You should possess good communication skills
You should be agile to quickly do some changes to your design
Final Verdict: DDD is not a silver bullet; it has its own challenges, so be pragmatic and decide whether to adopt DDD based on the nature of your project.
DDD, event sourcing and CQRS – theory and practice