It’s easy to see how Domain Driven Design (DDD) by Eric Evans was such a seminal work. It presents a holistic development process that seems to have predicted the next two decades of development trends. Here are some of my key takeaways from the book.
Domain-Driven Design is all about bringing together the business and the software. That means the people, the terms, models, and implementations.
- Devs must understand the business: Developers cannot be shielded from understanding the business or talking with domain experts. Domain knowledge is needed up to final implementation for success design.
- Domain Experts should understand the model: The software should reflect the domain and it’s language. The domain experts know the business better than you. If they don’t understand the high-level design, then it doesn’t fit the business and probably won’t accommodate change well (isolates the wrong volatilities).
- Language is important: Different or conflicting terms create division. Get everyone using the same language and use it everywhere, including code. A strong language leads to faster and deeper insights. Changes in language are changes in the design.
- Constant Refactoring: Understanding changes, and the code should follow. Keeping the code in line with business understanding leads to even more insights. Good design is needed to keep refactoring attainable.
The ideas from this book, especially from Part III, are a rigorous standard for good design that stands almost 20 years later.
Many ideas from DDD have found their way into the mainstream development. Though many were not originated by the book, but the book picked them out as important long before they reached mainstream.
To name a few
- Services: Stateless groupings of domain actions. Explicitly actions-only and not mixed with data
- Side-effect free functions: Functions should avoid changing external state as often as possible
- CQRS: Separate side-effects into their own actions
- Entities and Value-objects: A differentiation of data lifetime. Entities have identity beyond their contained values. Value-objects are only defined by their values. I.e. two value object instances with same data are interchangeable.
Other concepts have gained enough recognition that I knew them long before I intentionally studied DDD.
- Sub-domains: Most businesses can be broken down into multiple activities (departments?). These are good candidates for splitting the software to keep scope small.
- Ubiquitous Language: Language heavily effects communication and understanding of the domain. Thus, the whole team (devs and non-devs) should use one set of vocabulary about the domain. Changes in wording are changes to the design.
- Aggregates: The root in a hierarchy of data. Should be responsible for change controls.
Some have ideas yet to reach wide adoption, even if we know their good
- Self-documenting code
- Design by Contract: Advertise and enforce expectations for input, output, and side-effects.
- Declarative Design: The program states what more than how
- Names matter
- Specifications: Declaratively stating rules that data must obey. These rules can be used for validation or generation.
- Closure: Functions that have the same input and output type so they can always operate on their output (monad and monoids).
Personal Methodology Improvements
Much of DDD was already familiar to me from other sources. However, there were a few tips that demonstrated significant insights.
First, DDD recommends minimizing fields on entities. Instead, move as many as possible into value-objects on the entity.
This technique has two main benefits
- It’s easy to reuse the value objects and any functions for them
- Grouping fields enriches the domain model by raising questions about what data belongs together
Grouping entity fields in my own software revealed several implicit concepts the domain experts had intended, but not thought to explicitly call out. This improved understanding of the campaign tracking process.
Secondly, DDD recommends keeping an explicit document for the Ubiquitous Language.
My project already had an implicit shared language, but it had never been formalized. Pulling these shared terms into a glossary text file revealed very few terms around what was supposedly our core product!
The issue mostly stemmed from a lack of industry terminology. The core features were exploring new ground while the side-features met established industry needs. This mirrored our company’s own understanding of our core value and market challenge. Creating clarity in this portion of the model is an opportunity to clarify our advantage in the market!
I think DDD has survived the ages tremendously well. I only have one warning and one gripe.
The warning: this book is geared toward mature designers. Advice on keeping the design flexible is more about trade-offs than concrete direction. This is good, but it takes experience to leverage.
The gripe: Part II is outdated by it’s emphasis on Object-orientation. OO has not survived nearly as well as the rest of this book. This undermines much of the concrete implementation advice. Ironically, the book describes most of the practices that have since eclipsed OO, like service-orientation.
I highly recommend the updated domain modeling process described by Domain Modeling Made Functional.
Domain-Driven Design deserves it’s legendary status. It breaks false dreams of isolated of software design and calls out the intrinsic connection between good design and understanding the original problem. It weaves that value for understanding the problem into a solid process all the way from requirements to maintenance.