As applications grow bigger and bigger, our codebase needs to accommodate for more and more business actions. After a while you will have code that impacts a large amount of business actions without knowing exactly what they are. Changes to that code become more and more stressful. We had long been feeling the need to handle this complexity of our applications in a more explicit and clearer way.

In March 2016 we attended a 3-day workshop about Domain Driven Design by Mathias Verraes. This opened up a whole new methodology for us and we’ll be sharing our learnings through this and future blog posts.

What is Domain Driven Design?

Domain Driven Design aims to help you define the rules and actions of the business. By doing exercises like event-storming upfront, you get to discuss and find pitfalls in that business and its implementation. By then representing each of those rules and actions in your codebase, it becomes clearer what the intent and goal is.

It is not the holy grail to software development. If your application is simply about adding and managing records then a DDD approach is not as suitable and might even add more overhead.

If your software involves multiple contexts, has various types of products or has multiple departments then complexity is bound to rear its ugly head.

When making the choice between a DDD or CRUD approach take into account that businesses evolve and thus your software needs to evolve with it. Make sure you and your team know the direction the business is headed in before starting to build.


What is complexity in software development? Complexity describes the interactions between entities in your domain. When the number of entities increase, so do the interactions. At one point in time it would become impossible to know and understand all of these interactions.

More complexity in your software increases the risk of interference with the interactions, leading to bugs and regressions. Some parts of your software can even become so complex that it will be impossible to change.

We can identify different types of complexity.

Essential complexity

Also known as inherited or incidental complexity. It is directly related to the problem you are trying to solve with your software.

If your software has 20 features that make it easier for your users to manage the problem than those 20 features are considered essential complexity.

Accidental complexity

Not part of the problem you are trying to solve but stuff you have to deal with either way such as devops, writing tightly coupled code, managing microservices, etc.

It can also be introduced by adding features unrelated to the problem you’re solving.

Imagine you’re building a SaaS. At some point you will want people to register an account so they can use your service. This system has no influence on the solution to your problem but you have to add it to release your product.

It’s possible that at one point in time accidental complexity will become essential complexity.

Let’s have a look at Amazon. They are an online retailer and have been for a long time. Around 2003 they started to build an internal system that allows management of infrastructure by their development teams. They released this internal system to the public in 2006 and it is known today as Amazon Web Services, allowing developers to manage their infrastructure.

Identifying complexity

The best way to start identifying the complexity of your problem is by understanding it.

You can do this by researching the problem and talking to people that are familiar with it. The latter are usually the people asking you to build the software.

People that explain a solution to a problem are often optimistic and ignorant of the fact that something can and will go wrong. When everything goes right nothing seems complex. Try to identify this behavior and ask them how they would handle the situation in case something goes wrong.

Ubiquitous language

When you’re practicing DDD the language you speak becomes very important. Terms you use in discussions with the business need to come back in your model and codebase.

For example when building software for an inventory management system it’s more appropriate to say that an item was added to the inventory instead of it being created.

This also makes discussing this feature with the business easier.


DDD is all about putting the business first. The most difficult part about this is a change in your mindset. You will be forced to think in business rules first. An easy pitfall when starting to apply it is to keep thinking in CRUD systems. Most of the topics we touched in this post are far more involved and complex, they’ll be handled more detailed in future posts.

Other useful resources