Domain-Driven Design
posted on: Jun 5, 2018

After procrastinating for years due to its sheer size, I have finally picked up and started reading DDD. This is a must-read for developers of object-oriented software working on a complex domain. I found myself nodding on almost every sentence in this book, relating so much to my work at CityView, which has a super-complex domain of municipal software.

  • Every software program relates to some activity or interest of its user. That subject area to which the user applies the program is the domain of the software.
  • The heart of the software is its ability to solve domain-related problems for its user. All other features, vital though they may be, support this basic purpose.
  • To create software that is valuably involved in users’ activities, a development team must bring to bear a body of knowledge related to those activities. The breadth of knowledge required can be daunting. The volume and complexity of information can be overwhelming.
  • The messiness of most software domains is actually an interesting technical challenge. Creating a lucid model that cuts through the complexity is exciting.
Problems DDD solves:
  • When we set out to write software, we never know enough. Knowledge on the project is fragmented, scattered among many people and documents, and it’s mixed with other information so that we don’t even know which bits of knowledge we really need.
  • Domains that seem less technically daunting can be deceiving: we don’t realize how much we don’t know. This ignorance leads us to make false assumptions.
  • Domain experts are usually not aware of how complex their mental processes are as, in the course of their work, they navigate all these rules, reconcile contradictions, and fill in gaps with common sense. Software can’t do this. It is through knowledge crunching in close collaboration with software experts that the rules are clarified, fleshed out, reconciled, or placed out of scope.
  • Models are tools for grappling with this overload. A model is a selectively simplified and consciously structured form of knowledge. An appropriate model makes sense of information and focuses it on a problem.
  • Every model represents some aspect of reality or an idea that is of interest. A model is a simplification. It is an interpretation of reality that abstracts the aspects relevant to solving the problem at hand and ignores extraneous detail.
  • Useful models seldom lie on the surface. As we come to understand the domain and the needs of the application, we usually discard superficial model elements that seemed important in the beginning, or we shift their perspective. Subtle abstractions emerge that would not have occurred to us at the outset but that pierce to the heart of the matter.
Do we need Business Analysts?
  • In the old waterfall method, the business experts talk to the analysts, and analysts digest and abstract and pass the result along to the programmers, who code the software.
  • This approach fails because it completely lacks feedback. The analysts have full responsibility for creating the model, based only on input from the business experts. They have no opportunity to learn from the programmers or gain experience with early versions of the software. Knowledge trickles in one direction but does not accumulate.
  • A team of developers and domain experts collaborate, typically led by developers. Together they draw in information and crunch it into a useful form.
  • The constant refinement of the domain model forces the developers to learn the important principles of the business they are assisting, rather than to produce functions mechanically. The domain experts often refine their own understanding by being forced to distil what they know to essentials, and they come to understand the conceptual rigour that software projects require.
  • Domain experts have limited understanding of the technical jargon of software development, but they use the jargon of their field.
  • Developers, on the other hand, may understand and discuss the system in descriptive, functional terms, lacking the meaning carried by the experts’ language.
  • Across this linguistic divide, the domain experts vaguely describe what they want. Developers, struggling to understand a domain new to them, vaguely understand.
  • On a project without a common language, developers have to translate for domain experts. Domain experts translate between developers and still other domain experts. Developers even translate for each other. Translation muddles model concepts, which leads to destructive refactoring of code.
  • A project faces serious problems when its language is fractured. Domain experts use their jargon while technical team members have their own language tuned for discussing the domain in terms of design.
  • The terminology of day-to-day discussions is disconnected from the terminology embedded in the code.
The Solution: Ubiquitous Language
  • A project needs a common language. The domain model can provide the backbone for that common language, while connecting team communication to the software implementation.
  • The vocabulary of that UBIQUITOUS LANGUAGE includes the names of classes and prominent operations. The LANGUAGE includes terms to discuss rules that have been made explicit in the model. It is supplemented with terms from high-level organizing principles imposed on the model.
  • The model-based language should be used among developers to describe not only artifacts in the system, but tasks and functionality. This same model should supply the language for the developers and domain experts to communicate with each other, and for the domain experts to communicate among themselves about requirements, development planning, and feature.
How to Get There?
  • Initially the model may simply not be good enough to fill these roles. It may lack the semantic richness of the specialized jargons of the field. But those jargons can’t be used unadulterated because they contain ambiguities and contradictions.
  • It may lack the more subtle and active features the developers have created in the code, either because they do not think of those as part of a model, or because the coding style is procedural and only implicitly carries those concepts of the domain.
  • Persistent use of the UBIQUITOUS LANGUAGE will force the model’s weaknesses into the open. The team will experiment and find alternatives to awkward terms or combinations. As gaps are found in the language, new words will enter the discussion. These changes to the language will be recognized as changes in the domain model and will lead the team to update class diagrams and rename classes and methods in the code, or even change behavior, when the meaning of a term changes.
  • Committed to using this language in the context of implementation, the developers will point out imprecision or contradictions, engaging the domain experts in discovering workable alternatives.
  • Domain experts should object to terms or structures that are awkward or inadequate to convey domain understanding; developers should watch for ambiguity or inconsistency that will trip up design.
  • Recognize that a change in the UBIQUITOUS LANGUAGE is a change to the model.
  • When domain experts use this LANGUAGE in discussions with developers or among themselves, they quickly discover areas where the model is inadequate for their needs or seems wrong to them.
  • The domain experts (with the help of the developers) will also find areas where the precision of the model-based language exposes contradictions or vagueness in their thinking.
  • The developers and domain experts can informally test the model by walking through scenarios, using the model objects step-by-step. Almost every discussion is an opportunity for the developers and user experts to play with the model together, deepening each other’s understanding and refining concepts as they go.

Summary: Developers and domain experts have a close relationship. Domain-driven design crunches a huge amount of knowledge into a model that reflects deep insight into the domain and a focus on the key concepts. This is a collaboration between those who know the domain and those who know how to build software. Because development is iterative, this collaboration must continue throughout the project’s life.