Domain-Driven Design 101 — Move your first steps into DDD 🚶‍♂️

Daniele Scillia (Dan The Dev)
Learn Agile Practices
5 min readOct 26, 2023

🌟 We’ll take your first steps into Domain-Driven Design together, exploring the foundations of DDD and how it can transform the way you approach software development. 💡

A team of developers that reads a blue book titled “Domain-Driven Design: Tackling Complexity in the Heart of Software” and are happy celebrating what they are learning! Make at least one woman a member of the team, comics style.

⏩ Introduction

Software applications always evolve around the sphere of knowledge and activities that make up a company’s business. We need to learn how the company works, and how they use technology and then we explore ways to create our product or maximize our processes through our technical knowledge, which most of times means coding.

Domain-Driven Design is a software development approach that solves complex problems by connecting the implementation to an evolving model; it offers a set of tools aimed at designing and implementing code that delivers high business value.

When you start learning DDD, you start approaching the way you solve problems and develop software for your company in a more conscious way, because you build the domain knowledge you need to make conscious choices.

Let’s jump into the issue to discover the core concepts of DDD and how they can help make a difference!

🧩 A way to solve complex problems

This is the “enhanced version” of this old article I wrote on my previous Medium blog: since I lately improved my newsletter issues and gave this newsletter a lot more structure, and it was also time for discussing about DDD, I decided to revamp that article and expand it to make it even more valuable for new comers to DDD.

The first thing that is important to highlight, in my opinion, is that DDD aims to solve complex problems: a simple consequence is that it may be overkill if the complexity is not sufficient to justify it. This typically means that it’s very hard to see a startup having enough complexity to justify DDD from the beginning, especially because startups often are exploring new fields, meaning you don’t know enough of the domain.

The best thing to do when starting is keeping things simple, the smallest possible, with a good tested and clean enough code that allow you to move fast when you learn from the customer feedback.

Coming back to DDD, it basically offers two level of approaching problems, one called “strategic” and the other called “tactical”.

The Strategic Approach

The strategic approach helps the team make the best design and integration choices from a business competitiveness perspective. The company benefits much more from software modeled to explicitly reflect the organization’s competencies. Important concepts such as bounded context and ubiquitous language are defined here.

The definition of bounded context is that of a semantic contextual boundary. Within the enclosure of this boundary, each component of the software model has a specific meaning and specific responsibilities. The components that are within the boundary are specific to that context and semantically consistent with it.

On the other hand, the ubiquitous language is the language that is developed in a team working within a Bounded Context, spoken by every member of that team. Software models must be modeled consistently following that language, which is then both spoken among team members and implemented in code.

The Tactical Approach

The second approach described by DDD is the tactical approach, which helps the team design truly useful software that accurately models the business. The organization should benefit from various options to release the solution, with various infrastructure options, whether in-house or in the cloud. This is where aggregates are implemented.

To explain the concept of aggregate we must first mention those of Entity and Value Object.

An Entity is a software element that uniquely models an object. An Entity by definition always has a unique identity expressed through an ID that distinguishes its individuality from all other Entities of the same type. The entity is often mutable, therefore its state changes over time.

A value object, instead, is a software element that models an immutable concept. Unlike the model, we simply have a value that, contrarily to the Entity, does not have a univocal identification. The equivalence between value objects is in fact determined from the simple equality of their value.

A perfect example is the banknote: imagine modeling a 5€ banknote. Generally, within a business that requires payments, a €5 banknote is equal to another of the same value, they are perfectly interchangeable. But if our domain was instead a Mint, each banknote would require an ID to identify it uniquely because each of them is no longer interchangeable with the others.

Now back to the point: an aggregate is a composition obtained from one or more Entities and one or more Value Objects. Typically one of the Entities has the role of Aggregate Root, which is the main element. The aggregation of various elements of these two types then forms an aggregate that must have a transactional consistency boundary. This means that the state of the aggregate must always be consistent with the business rules in all its parts and therefore all necessary changes to the elements that compose it must be persisted simultaneously.

The Subdomains

Finally, to conclude this overview of the fundamental concepts of Domain-Driven Design, we need to talk about subdomains.

While the entire business the company deals with constitutes the Domain, a Subdomain is a section of that business. Subdomains can be used to logically subdivide the complete domain in order to understand the problems thereby breaking down the complexity. In DDD, Subdomains are ideally implemented as a clear Bounded Context.

Within a company’s subdomain, there are “Domain Experts”, people who understand very well the aspects that make up that part of the business because they work there every day. Not all subdomains are the same, however: we can recognize three categories.

The core domain is the most important subdomain because it means great results for the business; this is the subdomain in which the organization must excel and that can make a real competitive difference for the company if succeeds.

The supporting subdomains are less important than the core but are still important for the business because without them the core domain cannot succeed; it is a situation in which the company still wants to do custom development, even if not with the same investment put on the core domain, because we want to have control over them.

Finally, we have generic subdomains: you will typically find a lot of ready solutions on the market for them that you could buy, or you will decide to develop in outsourcing the solution — that’s because here the company wants to make the least investment possible to achieve what they need.

Until next time, happy coding! 🤓👩‍💻👨‍💻

Go Deeper 🔎

📚 Books

  • Domain-Driven Design: Tackling Complexity in the Heart of SoftwareThis is not a book about specific technologies. It offers readers a systematic approach to domain-driven design, presenting an extensive set of design best practices, experience-based techniques, and fundamental principles that facilitate the development of software projects facing complex domains.

📩 Newsletter issues

📄 Blog posts

🎙️ Podcast episodes

👨🏻‍🏫 Online courses

I can also focus my Personal Coaching service around DDD — discover more here.

🙏 Thank you for reading this shortened version of the article, you can find the full version on my blog here.

--

--

Daniele Scillia (Dan The Dev)
Learn Agile Practices

Software Engineer @TourRadar - Passionate Dev, XP Advocate, passionate and practitioner of Agile Practices to reach Technical Excellence