Domain-driven design is an approach of creating software, where our development efforts are focused on the heart of the software – the business domain.
Why even bother?
Would you like to be replaced by AI? Well, I assume you don’t, do you? Therefore, better move yourself out of the programming comfort zone and try to understand the business world.
Following DDD will help you to develop yourself into becoming a Technical Business Partner. Technical Business Partner is an IT professional, who fully understands the business she’s building. This means not only re-actively producing software according to business needs, but also being business-proactive. Thanks to this we are able to advice our clients regarding new business opportunities, build ubiquitous language and find inconsistencies in the existing business processes. With the advent of solutions such as ChatGPT, transformation from developer to Technical Business Partner has become more important than ever before.
At Leocode, we hire only the best Technical Business Partners that strive to fully understand true business requirements of our clients.
Domain – the problem space
Domain is the problem space of the business we are creating. Think all the complexities you usually experience when building software, but without any technical details.
Domain is what business is talking about all the time.
Solution space
Model we are creating belongs to the solution space. Defining strategic boundaries between modules, writing code that speaks business language, designing components according to true business requirements – it’s all part of the solution. Even sticky notes or tests are part of the model.
Ubiquitous Language
Our model should speak the same language as business. However, business rarely speaks exactly the same language. The same concept in accounting department might mean something entirely different by sales. It shouldn’t surprise you, though. Business is usually way more complex than we initially think. Context is the king.
Unfortunately, often naming is not consistent in the same context. It might work well up to some point for business, but is unmanageable when writing actual code. Therefore, we should aim to define the common language, used both by developers and business, given we are talking within the same context.
For example, let’s imagine we are working for a tree plantation. Within the “Growth” context, a Christmas tree is just a tree that needs some specific requirements regarding watering, soil, space, sun etc. At the same time, “Sales” department talks about number of orders and might be aware of an increased demand in December, so they can apply special Xmas “discounts”. On the other hand, for marketing, Christmas tree is nothing more than a product that should be aggressively advertised starting from late November.
It might happen that the “Growth” department inconsistently names important business concept. Some use term “tree”, others “Christmas tree” while for someone else it’s just a plant. They all mean the same thing, but name it differently. While it might be acceptable for human beings, it definitely messes things up and therefore is rather unsuitable when writing code. In such case, we should create the common language, that is being consistently used by business in everyday communication, documentation, tests and production code.
This common language is often named “Ubiquitous Language”.
Strategic patterns
In the previous section we’ve talked about language and contexts. Now, these contexts need to communicate somehow. With the growing number of contexts, it can be hard to manage all the relationships. This problem can be solved by applying DDD strategic patterns.
There are multiple strategic patterns we can apply when integrating contexts. For example:
- Customer-Supplier
- Open Host
- ACL
- Conformist
- Separate Ways
- Shared Kernel
- Partnership
- Published Language
We won’t cover all the details here, as it’s out of scope of this article. We can use Context Maps to draw all the relationships between contexts of our domain. That’s how the context map looks like.
However, strategic DDD is more than just context maps. It’s equally important to organize teams around contexts identified in the map. Thanks to this, we can explicitly define relationships and boundaries between teams. For example, we might notice we are overusing the conformist pattern, while we should follow Customer-Supplier between specific teams.
Strategic thinking can also help us to identify layers in our domain model. Again, this is something we should cover in a separate article.
Tactical patterns
Strategic patterns help us to understand why and what we are building. Tactical patterns, on the other hand, are useful to answer how we want to implement our model.
Tactical patterns are usually easier to understand for developers, as they can be applied immediately to the code. Some popular tactical patterns include:
- Aggregate
- Domain Service
- Domain Event
- Policy
- Repository
- Domain Factory
- Module
You probably might’ve heard about these patterns already and maybe even tried some of them. These patterns are usually the first thing developer tries when learning DDD.
However, based on my experience, we shouldn’t be forced to look for these patterns immediately when we start a new project. When you start facing some problems, the need for these patterns will become evident.
Also, don’t forget about strategic patterns – these often have much bigger impact on the project.
DDD vs OOP
Some might say that DDD is the OOP done right. I can’t agree with this. DDD doesn’t enforce you to use OOP. You can implement most of the tactical patterns using FP, for instance. When you follow DDD, you are concerned about behaviors, not structures. For example, aggregate is nothing more than something to guarantee some business invariants. It doesn’t have to be a group of objects. It might be implemented as a function, simple CLI application, database procedure/constraints or even as a completely separate service. It doesn’t really matter. The big idea is the behavior.
However, one thing remains true. If you decide to use OOP, then DDD will definitely help you to make the best out of it.
Summary
Hope you enjoyed the article. It’s just the first installment of the DDD series. Stay tuned for new content coming up pretty soon!
Author: Mike Wojtyna