The success of any given software project can be distilled to a rather simple definition or rule: we need to build the right thing, and we need to build this thing right.
It is a very abstract and simple if not primitive definition. Nevertheless, it is the one that is hard to argue with.
Building the right thing
Building the right thing… I don’t think it is necessary to emphasise the importance of this claim. But who knows what does the right thing look like?
Domain experts. The domain expert is not a real position, it is rather a title that derives from a solid background in the industry. It might come from the direct experience, gained by actually working in the field (e.g. doctors, pilots, accountants). Or indirect, gained by working with other domain experts for an extensive period (designers, developers, business analysts).
Domain experts might or even will have unrelated roles and responsibilities, but one thing they all have in common… Domain knowledge.
In high-complexity domains, we can discover another layer of people with the sole purpose of helping in interfacing with domain experts’ experience and expectations. Unavoidably these people will become domain experts on their own, gaining a lot of indirect experience.
You can distinguish domain experts by the language they use. It might sound rather confusing at first. Overflown with terminology, rich in acronyms and double-meaning words.
Building the thing right
Building the thing right… Speaks to itself. No one appreciates broken software…
There are always numerous ways to solve a problem, hence to build an application. It is a well-known problem among developers, the attention gets easily carried away from the end goal of the project to the end tech.
When starting a greenfield project every developer feels like a kid in a candy shop.
Balanced, constantly refined architecture that focuses on the project goals is a key to building the thing right.
Depending on the scale of the project, there might be a mixture of different roles and positions that will keep an eye on the architecture and tech-stack integrity and alignment. Solution architects, tech leads, CTOs, you name them. No doubt, you will find domain experts among them, usually they will have a long history with a company or in the given industry. And of course they will use distinguishable (domain) language.
Building the right thing right
Appears, most of the time we know how to build the right thing and we have domain experts who can provide all the necessary support for it. And we know how to build the thing right and we have the software engineering forces to facilitate it. So why it is so hard to build the right thing right?
I think no surprises will be here, communication is hard…
Any organization that designs a system will produce a design whose structure is a copy of the organization’s communication structure.
— Melvin E. Conway
A so-called Conway’s law states that communication significantly impacts the architecture, design, and code base. In the complex domain where a lot of convoluted logic resides around every corner, even initial unintentional miscommunication can derail the project. Any misinterpretation, if not addressed in time, starts a mismatch snowball effect. It grows fast, creates confusion and frustration, and degrades code-base quality which quickly becomes unmaintainable and error-prone. Even if the original miscommunication is fixed, usually it happens too late and the project is doomed.
Communication gap
Original miscommunication often appears from both the domain expert’s bias and the developer’s unwillingness to clarify details.
Because of the domain expert’s vast experience in a certain area a lot of the important details are obvious, certain aspects are given and don’t require clarification, if not mentioning. The language is overflown with opaque acronyms and words that convey an indelicate meaning. This is expected and unavoidable. The domain language is a habit that domain experts develop with years of experience. It is a framework they use for efficient communication. Medicine, mathematics, accounting, industrial design any professional area will be rich in terminology. Academical or specialised books, can’t guarantee the definition of the domain language, although they are likely to embody its essence; what you will hear from domain experts is what domain language is…
Communication in general and clarification specifically is a very laborious process that requires decent self-effort. Cognitive work reduction and mental-resource preservation are part of human nature. Unmotivated developers don’t try to clarify the terminology or suspicious words, or address ambiguity in definitions. Instead, we subconsciously try to self-explain any logical flaw or uncertainty, ignore unclear acronyms, and don’t question obscure logic or abrupt conclusions.
We’ll talk about the domain model a bit later…
Unfortunately, experienced and reliable domain experts together with talented software engineers don’t guarantee the success of the project.
Domain-Driven Design
DDD can be perceived differently from different perspectives. It is a philosophy, a framework, a set of architectural patterns, and many more things with the ultimate purpose of building the right thing right.
Domain-Driven Design is an approach to software development that centers the development on programming a domain model that has a rich understanding of the processes and rules of a domain.
– Martin Fowler article Domain-Driven Design
Domain-Driven Design (DDD) suppose to bridge the gap between the domain, its model, and implementation. It supposes to tide over misapprehension between those who can build the right thing and those who can build the thing right by making the Domain Model a centerpiece of the communication and implementation process.
Holistic Domain Model
The Domain Model is a root element of the Domain-Driven Design, everything spins around it. However, it is often confused to be one big diagram that encapsulates everything. Although nothing is wrong with having a big diagram, we all like big diagrams; except maybe we don’t like to keep them up to date, but that is a different story I suppose.
The truth is the diagram is a vital piece of the Domain Model, but so are the ubiquitous language, the code base, and even your and your colleagues’ mental model. Which ideally should all match and represent Holistic Domain Model.
Model-Driven Design discards the dichotomy of analysis model and design to search out a single model that serves both purposes. Setting aside purely technical issues, each object in the design plays a conceptual role described in the model. This requires us to be more demanding of the chosen model since it must fulfill two quite different objectives.
— Domain Driven Design: Tackling Complexity in the Heart of Software by Eric Evans
Having a Holistic Domain Model can lead to rather unexpected outcomes. With a minimum support domain experts should be able to read the code and understand it. Because variable names, classes, and abstractions are part of the Domain Model, therefore meaningful to everyone involved.
Consider this example where we are committing a backlog item to the sprint
|
|
Versus this example, where we are doing the same thing, but we match the ubiquitous language and preserve our Holistic Domain Model integrity.
|
|
Few words about the code…
Since we touched on this topic, I’d like to add a few short words about the code and architecture. I won’t go into the depth of it, as quite a few books doing it better than I would. And I might share my thoughts about it in further articles. Anyhow…
DDD is heavily relying on object-oriented concepts, it builds enriched object abstraction on top of the classical object model. DDD introduces a certain object classification, such as Entities and Value Objects. Provides isolation tools and interaction interfaces such as Aggregates and Aggregate Roots.
Unlike many modern approaches, DDD does not appreciate Anemic Model and defines it as an anti-pattern. It emphasises the importance of keeping domain objects together with domain logic. So classes know what they are and what they can do instead of being data transfer objects.
DDD recognises the complexity of every domain and hence does not attempt to fit everything in one bowl. It emphasises the importance of segregation and boundaries between different contexts and introduces a set of patterns to construct anti-corruption layers.
DDD works very well with Event Sourcing and Event-Driven Architecture in general.
Bottom Line
The idea of importance mature and well-developed domain and its model was around for a while. And intuitively recognised by almost anyone involved in the implementation process, yet somehow it fades and gets lost in the daily development routine.
The DDD is something anyone can start applying and practicing today on any project. The more sophisticated the project, the more beneficial it will be, nevertheless even lighter projects can benefit from it
I would highly recommend familiarising yourself with it, as it will guarantee a change in your approach to design and development.
References
- Thinking, Fast and Slow by Daniel Kahneman
- Thinking in Systems by Donella H. Meadows
- Domain Driven Design: Tackling Complexity in the Heart of Software by Eric Evans
- Implementing Domain Driven Design by Vaugh Vernon
- Learning Domain-Driven Design: Aligning Software Architecture and Business Strategy by Vladik Khononov
- Design and Reality: Essays on Software Design by Rebecca Wirfs-Brock and Mathias Verraes