Five Tips On Domain-Driven Design

Osman Başkök
Trendyol Tech
Published in
8 min readJan 18, 2021

Domain-Driven Design (DDD) is a software development approach that offers a useful and powerful set of tools to help create a well designed and business aligned software in a more maintainable way. Domain-Driven Design has been around for nearly two decades now. The concept was first introduced to the software world in the book named “Domain-Driven Design: Tackling Complexity in the Heart of Software” (a.k.a. The Big Blue Book) which is written by Eric Evans. He published his book -after 5 years of work- in 2003. In his book, Eric Evans put together all his answers to the common problems he faced in complex and enterprise business application projects. In the early years of the book the concept that it brings was not quite easy to understand but rather it was slightly too much theoretical and abstract. This is perhaps the main reason why DDD gained the popularity it deserves a little too late.

In the last decade, software engineers like Vaughn Vernon, Scott Millet, Nick Tune, Udi Dahan and some others who are considered leading experts on DDD have published many articles and books on the implementation details of Domain-Driven Design. By the examples they provided, how DDD can be applied in practice became clearer and more concrete for the software world.

Today, we have a wide variety of sources to learn it from and more programmers who have been influenced by Domain-Driven Design all around the world. Everyday more projects are being developed using DDD approach. However, not all can be considered as good implementations of it. There are still some common misunderstandings and confusions about this concept. In this article we will try to clarify some of them and find answers to the questions like; What do we expect from DDD? When do we need to use it? Is it always the right choice? Is it even worth learning? etc.

Not A Silver Bullet

Domain-Driven Design is nothing magical. It doesn’t take your project to the moon. Besides, it definitely requires a good knowledge and a serious amount of effort for a successful implementation. We need to absorb each tool (pattern) it provides and apply them properly. It is crucial to understand the importance of Ubiquitous Language, Domain Modeling, Context Mapping, extracting the Bounded Contexts correctly, designing efficient Aggregates etc.

As the project keeps living, the ubiquitous language can evolve, the domain model might need to be revised, also the bounded contexts might need to be split or even merged as well as the aggregates, we can have new clients and new types of relationship with other services, refactoring needs to be continuous and so on… It is important to notice and answer all these needs as soon as they arise in order to sustain a successful DDD implementation. Domain-Driven Design pays off as long and much as you stick with this discipline. What you will get in return is a project that is better aligned with the business needs and highly maintainable (loosely coupled, readable, reusable, extendable, easy to refactor, etc.).

Initial Difficulty of Learning

Domain-Driven Design concept is often misunderstood by the programmers who have no or limited knowledge about it. Usually it’s thought to be a single design pattern or a software framework or sometimes a library. When you do a little research, you will see that most of the time it is called one of the followings; an approach, a philosophy, a concept, a discipline, a set of principles, etc. And all these are -in fact- the correct definitions for Domain-Driven Design. They may sound abstract at first and may not make much sense but it’s just quite normal for such a big subject.

It was 2017 when I first started reading about Domain-Driven Design and it took long for me to figure out what it really is about. I read a lot of articles and watched Youtube videos about it, but at some point, I just realized that I can’t organize my learnings and end up with more and more questions in my mind. Ok, it wasn’t the thing that I thought it was at the beginning! I would need to take it more seriously and go more systematically if I really want to learn it. So I started reading several books beginning with The Big Blue Book, studied some large projects which are developed with DDD approach. And finally I started feeling more confident about it. Nevertheless, today there is still much to learn and experience for me in DDD.

Domain-Driven Design Learning Curve

Domain-Driven Design can be considered as a living system. It improves and expands over time. Since it consists of many different patterns, there could be new ones in the future to join among them. For example; when The Big Blue Book first came out, there wasn’t a pattern called Domain Event in it. Eric Evans decided to add this pattern in his book in 2009. Another example is Layered Architecture. Unlike the first years of the book, we now have alternative architectural choices that fit very well with DDD approach such as Hexagonal and Onion Architectures. So as DDD evolves, we will have to keep up with it and learn about the new advancements not to stay obsolete!

Domain-Driven Design is not something that we can absorb within several days or several weeks. Before we decide using it in a project, it’s very important to have some certain level of knowledge and confidence about it.

Not Always The Right Choice

“The essential thing about Domain-Driven Design is that you have to care more about the business or the domain that the software is being targeted at…”
- Eric Evans

“The goal of Domain-Driven Design is not to simply produce better software but to enable better business outcomes.”
- Scott Millet

Domain-Driven Design is all about business, complex business. Let’s call it Business Driven Design for a moment. A design that is driven by business. A software design that is driven by business experts, business rules and business activities. Not by technical people nor technical point of view. Thus, in return it gives a better output to answer the expectations of business people. So it’s very clear that Domain-Driven Design is an option only when we create business software.

“Business software (or a business application) is any software or set of computer programs used by business users to perform various business functions. These business applications are used to increase productivity, to measure productivity, and to perform other business functions accurately.”
- Wikipedia

Considering this definition of business software, do you think that a computer game is a kind of software that is used by business users and measures productivity? Or an operating system? How about a device driver? Or a dictionary application?

We usually see the term “enterprise” along with “business application” in the Domain-Driven Design definitions. The terms “enterprise application” and “business application” are highly engaged and often used together. Martin Fowler explains enterprise application as;

“… one particular form of software — things like health care records, foreign exchange trading, payroll, and lease accounting. These are very different to embedded software inside printers, games, flight control software, or telephone switches…”

“Enterprise Business Application” terminology also helps us to clarify the target area of use for Domain-Driven Design.

Above we mentioned that Domain-Driven Design is not only about business but complex business. The tools DDD offers aim to organize and reduce this complexity. However, we first need to evaluate the business complexity in our project to see if it’s worth bothering DDD.

Business complexity can be relative and hard to figure out. Luckily, we have Vaughn Vernon’s DDD Scorecard (See the book Implementing Domain-Driven Design) to help us out at this point. In his scorecard, Vaughn Vernon lists 6 different aspects of business complexity. Each aspect has its own weight from 0 to 5 that affects the total point. If the total point -at the end of the evaluation- is 7 or higher, it means a go for DDD.

Other than Vaughn Vernon’s scorecard, we can ask some questions like the following to have an idea about the business complexity of our project.

How many business units (services) does the business have? Do these units have strong dependencies to one another? Is the business growing/expanding? How many business rules are we talking about? 10, 20 or many more? etc…

Domain-Driven Design is not for free, it comes with a cost. The cost of learning, the cost of implementation, the cost of maintenance, etc. I personally recommend you not to bother using it for simple business projects that could take like 1–2 months to complete.

Beware DDD-Lite

Many of the DDD-like implementations are not actually DDD. Calling a project DDD just because it has aggregates, value objects, factories, repositories, events etc. is a common mistake. Domain-Driven Design is not an architecture. And it’s much more than just coding.

“DDD-Lite is a means of picking and choosing a subset of the DDD tactical patterns, but without giving full attention to discovering, capturing, and enhancing the Ubiquitous Language. As well, this technique generally bypasses the use of Bounded Contexts and Context Mapping.”
- Vaughn Vernon

DDD-Lite is a pitfall! Ignoring the strategic part of Domain-Driven Design leads to poor domain models. Applying poor domain models into code will eventually lead to a product that is not quite aligned with the business. Such projects may end up with extensive refactoring or even complete failures.

Ubiquitous Language is considered to be the most important pattern of all DDD patterns since it is the entry point for a true DDD implementation. Understanding the problem space is only possible when this pattern is properly applied. Following this, with Model-Driven Design -where the problem space meets the solution space- we discover the domain models, the sub-domains, the bounded contexts and the relationships among the bounded contexts. Now think about skipping all these steps and starting to code!

Simply without understanding the problem, we cannot come up with a solution. For this reason, the strategic part of Domain-Driven Design deserves to be paid a higher importance in DDD.

Strongly Applied OOP

Object-Oriented Programming is one of the main ingredients of Domain-Driven Design. It has serious advantages when representing the domain model in the code base. The idea behind OOP Paradigm is to keep data and behaviors together which provides modularity, reusability and a higher cohesion for the business logic.

Aggregates are the important components of a DDD implementation. The main role of an aggregate is to enforce consistency and invariants through behaviors and encapsulation. Thus, the flow gets organized around the aggregates (as well as the other entities). This idea is fully supported by OOP languages, since OOP Paradigm allows you to design rich domain models.

On the other hand, it doesn’t mean that applying Domain-Driven Design in a functional language is not possible. You can still do that in an anemic approach and find some examples of it that are shared in public git repositories.

Thanks for reading :)
If you have any questions, feel free to contact me…

--

--

Osman Başkök
Trendyol Tech

Software Engineer for over 15 years, interested in Architecture and Design, DDD, Extreme Programming, Agile and Testing