Domain Driven Design: Your Whole Dev Team Speaking the Same Language
Use domain driven design to maintain software code that mirrors the actual domain to which it refers. This ensures that all stakeholders speak the same language from the start of the project to final deployment.
In the prehistoric days of software development, product managers would hand a stack of documents to developers who would then disappear for two or three months. When they returned with the product, everyone would hold their breath and inspect it to see if it met expectations. If it didn’t, a lot of wasted time, money and costly rework were the result.
Why would businesses make such risky bets on developers? In short, because they don’t know jack about code. But thankfully, there are now more inclusive development paradigms to prevent such debacles. Without a doubt, one of the best is domain driven design (DDD). This is because it puts the client’s business at the center of development right from the very beginning -- nay, even before the technical start of development, before a single line of code is written. This results in total clarity regarding the business as represented in the software, including all its parts, their relationships and, more crucially, their terminology. The scope of all of those things as a whole is what is meant by the term “domain” in domain driven design.
Not all software developers use domain-driven, plain-language methods. This may be because they don’t want to do the upfront work it takes to understand the client’s business, or they simply lack training in the method. Some may even engage in a practice whereby they write difficult-to-decipher code so that the client will be less able to transfer it to another company to run for them, i.e., “security by obscurity.”
Clients would do well to learn the basics of domain driven design to ensure that the developers they hire adhere to its most important tenants at the least. It is the technique most favorable to clients since it reduces cost, rework, time to debug and also enables agile iteration, which is key to staying competitive in today’s digital business landscape where up-to-date software is an increasingly important part of your offering. But most importantly, it allows to business to ensure its domain-specific requirements are reflected in a understandable and sustainable way
What’s in a Domain?
Domain driven design (a form of behavior driven development) maintains that software code should mirror the actual domain to which it refers. This means both the structure and language of code -- class names, class variables, class methods, etc. -- should match the real-life domain as closely as possible.
The domain is usually a particular business domain, but it can be any sphere of knowledge, objects, activity, etc. In other words, it’s all the parts that make up the thing for which the software is being developed, taken as a whole. It might be a company, with its inventory, employees, customers, activities, etc. It may be any number of other things, for example, an educational course with its teacher, students, required texts, tests, so forth. DDD takes such real-life contexts and their contents and renders them in the form of a software program.
Key Concepts in DDD Include:
Domain - The main sphere of knowledge, activity, etc. for which the software is being created.
Ubiquitous Language - A language that describes all domain elements, activities, methods, etc., strictly adhered to by all parties to the software project to understand, plan, build and discuss the software and its behavior.
Model - A system of abstract descriptions of certain domain aspects that can be used to solve domain problems.
Context - A particular setting within the domain that determines how a term or group of terms appearing in it are to be interpreted. A single context extends just as far as a single model can extend without compromising its conceptual integrity.
Context Mapping - Large software projects often give rise to multiple distinct models and contexts. It’s important to keep them separated to avoid confusion, miscommunication and bugs. Bounded Contexts explicitly define the areas where a particular context takes effect, or a particular model is to be applied. They may conscribe, for example, the “Sales” model in one bounded area and the “Support” model in another.
Mapping bounded contexts visually is quite helpful for teams. It can solve the tug-of-war between single terms in DDD’s ubiquitous language. In the above example, the term “Customer” may be used in both contexts but have somewhat different meanings and functions within each. Bounded contexts ensure that everyone understands what “Customer” refers to in the Sales context versus the Support context.
In English, Please
Plain, human-readable language is at the core of DDD and is what makes it superior to other development methodologies in many people’s minds, and particularly from a business client’s standpoint. It opens channels of communication between teams, enables the business to understand and agilely, iteratively, direct the design of software as it is being built, and it prevents a situation where the business can’t transfer the code due to obscurity.
DDD developers need to become adept in best practices around naming conventions. They include:
- Choose easily readable identifier names
- Keep code as brief as possible, but, ultimately, favor readability over brevity
- Don’t use abbreviations or contractions in identifier names
- Don’t use acronyms that are not well known, and even if they are, only when necessary
The purpose of these principles is to write more human readable code and prevent the need for familiarity to quickly understand what is going on in a given code block or specific line. Below is an example of code taken from bad to better to best with DDD best practices:
var wo = GetSomethingFromAService(); //
(Requires context outside of line to understand "wo.")
var workOrder = GetSomethingFromAService(); //
(We know this is a work order, but is it an entity or model?)
var workOrderEntity = GetSomethingFromAService(); //
(We now know this is an entity work order, not a model work order.)
Identifier names can get as long and detailed as needed in order to tell a technical or non-technical reader what the purpose of the code is.
Call it what it is -- but only once everyone agrees on what to call it
I’ve worked with some otherwise great developers who’d absorbed some technical knowledge about DDD, rolled up their sleeves, and said, “I’ll just name everything exactly what it is.” At which point, I’d swivel their chair away from their computer screen and interject, “Not so fast.”
You see, the most critical part of DDD begins before a line of code is ever written. That’s because computer programs do not like ambiguity and rarely miss a chance to make it known. Therefore, there can be zero ambiguity in the naming of elements in a domain. Everyone on the team or teams -- on both the business and the development sides, whether they total five, fifty, or a hundred and fifty people -- must reach complete agreement on what all domain terms mean.
Developers may think it’s safe to make assumptions about the naming of some elements.
For example, a developer might contest, “Well, this right here is obviously a widget, so there’s no point asking the product owner if everyone at the business agrees that it’s a widget. It’s self-evident.”
The correct response to this common line of thought is: Obvious to whom? Self-evident to whom? The truth is that lack of agreement on what domain objects are named is common even when team members least suspect it. And even small assumptions can lead to big bugs, inaccuracies and breakdowns in a finished software program.
It’s important to understand DDD not as just a technical method for programming, but a pathway for frictionless communication between software developers and their clients.
"Domain driven design is really a solution to the knowledge gap between the people who are building software and the people who are asking the engineers to build the software for them," said Robert Lara, software engineer at CMHWorks. And it had better be the developers bending over backwards to understand and adopt their paying clients’ preferred terminology -- not the other way around. It may be true that every company is becoming a software company, but that doesn’t mean it is feasible for business people to learn coding. Ideally, developers will increasingly adopt the language of the business and embed it into the software, so it’s easily understood by technical and nontechnical people alike. That’s a task that DDD is tailor made for, and it begins with an effort to build a glossary of terms the business prefers to describe the domain.
Here are some guidelines and tools to make the initial baselining of domain language as brisk and easy as possible.
Give the Business the First and Last Say
The business should be the authority in naming the domain elements. This prevents time-consuming disagreements and confusion. The first step is to have them set forth all the domain terms they know. These can eventually be placed within bounded contexts and mapped out through the larger domain model. If a new term comes up, place it in its proper place in the domain.
Build a Glossary
Maintaining a complete glossary of domain terms will serve both developers and clients very well for as long as they work together. Organize it alphabetically, by context, business segment, team and any other rubric that may help you reduce search time and be more efficient. And remember to keep it updated.
Visual Paradigm’s Glossary Grid is one very good tool. You can also make a glossary in a program you probably already have like Microsoft Word, Excel or Google Docs.
CMH has one particular client with a very obscure business model. Its domain contains a lot of acronyms, various unusual types of procedures, purchases, purchase orders, products, etc. We just onboarded several new developers who would have faced a very steep learning curve in decoding all that language if not for the glossary we documented for the project. They all read through it, and we have not had a single instance of confusion when talking about user stories, etc.
Put Domain Terms Where All Eyes Can See
Make the glossary openly viewable to all project participants on both the development and business side. Applications like Microsoft Teams, Slack and Basecamp have features for group collaboration and posting. Get everyone to personally sign off on the definitions of all terms.
With all terms unambiguously defined, known and easily searchable if needed, everything about development just runs smoother. Talks about user stories have fewer hiccups; developers, business people, QA managers and even customer service representatives can all fluidly exchange ideas, note issues and agree to changes amongst each other. Unambiguous language at the code level helps teams write better tests that are less likely to fail what should pass or vice versa. Debugging has less guesswork, searching, asking, waiting for answers, etc. When a rep says, for example, users keep complaining about a character limit in the search field, the developer knows exactly what the rep is talking about. The developer will be able to find it right away -- perhaps the precise code lines to fix are even named “search field” and “character limit.” How easy is that?
To illustrate the difference made by code based on unambiguous language, we’ll take a particular CMH client as an example. The client asked us to redesign an internal application -- we’ll call it version 4 -- to replace an old one we’ll call version 3.
“When it came to calculating figures, there were calculations all over the system. And if there was ever something that wasn't calculated properly, you didn't really know where the calculation was; you didn't know what it was called; you didn't even know which programming language that calculation would be calculated in,” Lara said. “And that caused havoc in trying to fix bugs.”
Changing just two or three lines of code may have required an engineer to investigate three different system parts, decipher three distinct code languages and fix the problem in multiple different locations.
Since CMH redesigned the application with a DDD foundation and framework, calculations in the system are easy to locate. There is no longer any “hunting” through the code for where they may be hiding, because it’s literally spelled out. And debugging is much easier and much cheaper. "The client has responded that the turnover for bugs is drastically faster with the new app,” Lara said.
There is enough additional technical material about DDD to fill a couple of fat books. Eric Evans’ seminal Domain Driven Design is one obvious recommendation. Just remember that without a ubiquitous language that is unambiguous and unanimously agreed upon, none of that other stuff amounts to a hill of beans.
To be clear, DDD is not appropriate for all Software Development projects and should be reserved for complex or esoteric domains to clearly represent the language, terms, events, and controls necessary to deliver a clear and concise domain model. Why? Because simple projects with simple or standard domains don’t necessarily need to incur the extra cost. These are the kinds of decisions that can make or break a project and what separate real developers from hobbyists. Now as an educated consumer of software, you know what to ask.
The development experts at CMHWorks would love to talk with you about executing your next software project. Get in touch with us today if you want it built right the first time and maintained the right way all the time.