When using the core philosophy and the practices of Domain-Driven Design (DDD) as guidelines for software design and development, they can be summarized in three principles: Capture – Embed – Protect, Steven A. Lowe claimed in his presentation at this year’s DDD eXchange conference. We capture the domain model by understanding just enough to take positive actions. We embed the model in the code and in the conversations. We protect the domain model from corruption from other domains, especially technical ones.
For Lowe, principal consultant at Thoughtworks, DDD was a breakthrough when it emerged because it destroyed the flawed obsession with enterprise data models and replaced them with cooperating domain-focused and self-contained yet overlapping models. He emphasizes that DDD changed the focus and scope in software development from a technical point of view to having the business goals guide our exploration and solutions. He believes though that DDD still suffers from some "myths", but claims that they are all false:
- DDD is hard. No, it requires focus and self-discipline, but so does programming.
- DDD brings overhead. Only if you think that learning about a domain is unnecessary.
- DDD is just for complex domains. They may need it the most, but the mindset is always appropriate.
The goal of capturing is to make a mental model of the domain visible and interactive so that everybody can agree on it. One way of creating models that Lowe recommends is getting everyone involved into a room and then focus on the events in the domain. This is a technique called Event Storming, a group modelling approach created by Alberto Brandolini, that Lowe has found to be extremely powerful, a way of maximizing the learning speed with minimum effort.
When embedding a domain model in code, two important parts are naming things so that they reflect domain intentions, and composing things so that they reflect the behaviour of the domain. Lowe notes that if you can’t come up with a good name for a thing, then maybe you don’t understand what you are naming well enough. Since both documentation and diagrams can be out of date, the code is the only reliable source of truth. By embedding the domain model into the code, the model is always correct and available for developers. At a high level, the code can also be read and understood by domain experts.
To protect a domain from corruption we use boundaries to separate subdomains from each other. The boundary of a context is its interface, i.e. the commands and events going in and out. But the strength of the boundary is also important, what kind of validation and translation is done in the interface? A practical way of protection is using modules to physically separate subdomains. The advantages include a less coupled and more resilient codebase. Lowe notes that not coding a technical debt in the first place is easier than removing it later.
Lowe concludes by emphasizing that capture - embed - protect is an iterative process with each step done multiple times, incrementally building up a domain model from smaller validated models. He also notes the importance of making domain-driven design thinking ubiquitous; if you don’t intentionally model the domain, you will unintentionally model something else.