Ubiquitous Language

AUDIENCE

Programmers

Our whole team understands one another.

Try describing the business logic in your current system to a domain expert. Can you explain it in terms they understand? Can you avoid programming jargon, such as the names of design patterns, frameworks, or coding styles? Is your domain expert able to identify potential problems in your business logic?

If not, you need a ubiquitous language. It’s a way of unifying the terms your team uses in conversation and code so that everybody can collaborate effectively.

Speak the Same Language

Programmers should speak the language of their domain experts, not the other way around. In turn, domain experts should tell programmers when the language they’re using is incorrect or confusing.

By “language,” I mean the terms and definitions your experts use, not their literal native language. Imagine you’re creating a piece of software for typesetting musical scores. The publishing house you’re working for provides an XML description of the music, and you need to render it properly. This is a difficult task, filled with seemingly minor stylistic choices that are vitally important to your customers.

In this situation, you could focus on XML elements, parents, children, and attributes. You could talk about device contexts, bitmaps, and glyphs. If you did, your conversation might sound something like this:

Programmer: “We were wondering how we should render this clef element. For example, if the element’s first child is “G” and the second child is “2,” but the octave-change element is “-1,” which glyph should we use? Is it a treble clef?”

Domain expert (thinking, “I have no idea what they’re talking about. But if I admit it, they’ll respond with something even more confusing. I’d better fake it.”) “Um…sure, G, that’s treble. Good work.”

Instead, focus on domain terms rather than technical terms:

Programmer: “We were wondering how we should print this “G“ clef. It’s on the second line of the staff but one octave lower. Is that a treble clef?”

Domain expert (thinking, “An easy one. Good.”) “That’s often used for tenor parts in choral music. It’s a treble clef, yes, but because it’s an octave lower, we use two symbols rather than one. Here, I’ll show you an example.”

The domain expert’s answer is different in the second example because they understand the question. The conversation in the first example would have resulted in a bug.

How to Create a Ubiquitous Language

Ubiquitous language doesn’t come automatically. You have to work at it. When you talk to domain experts, listen for the terms they use. Ask questions about their domain, sketch diagrams that model what you hear, and ask for feedback. When you get into tricky details, ask for examples.

For example, imagine you’re having your first conversation with a domain expert about the music typesetting software:

Programmer: I took piano lessons as a kid, so I know the basics of reading music. But it’s been a while. Can you walk me through it from the beginning?

Domain expert: We typeset music for ensembles and orchestras here, so it’s not exactly the same as a piano score, but your background will help. To start with the basics, every score is divided into staves, each staff is divided into measures, and notes go into the measures.

Programmer: Got it. So the fundamental thing we’re typesetting is the score. (Draws a box and labels it “score.”) And then each score has staves. (Adds a box labeled “staff” and draws a line connecting it to “score.”) And each staff has measures. (Adds another box labeled “measure” and connects it to “staff.”) How many staves can the score have?

Domain expert: It depends on the arrangement. Four, for a string quartet. A dozen or more for an orchestra.

Programmer: But at least one?

Domain expert: Well, I guess so. It wouldn’t make sense for a score to have zero staves. Each instrument gets a staff, or multiple, in the case of instruments with a lot of range, like pianos and organs.

Programmer: Okay, I’m starting to get lost. Do you have an example I can look at?

Domain expert: Sure. (Pulls out example.5) Here at the top, you can see the choir. There’s a staff for each part, which you can think of being the same as an instrument: soprano, alto, tenor, and bass. And then a grand staff for the harp, a grand staff and a regular staff for the organ, and so forth.

Programmer: (Revising sketch on whiteboard.) So we start with the score, and the score has multiple instruments, and each instrument has one or more staves, and the staff can be either a regular staff or a grand staff. And it looks like the instruments can be grouped together, too.

Domain expert: Right, I should have mentioned that. The instruments can be grouped into sections. You know, string section, horn section?

Programmer: (Revising sketch again.) Got it. Score has sections, sections have instruments, and then the rest.

Domain expert: (Looks at diagram.) This is a start, but there’s still a lot missing. We need a clef, key, and time signature…

The result of this conversation is more than just a whiteboard sketch. It can also form the basis for a domain model [Fowler2002] (ch. 9) in your code. Not every program needs one, but if your team’s software involves complicated domain rules, a domain model is a powerful way to develop.

You’re not going to literally program in the domain experts’ language, of course. You’ll still use a programming language. But you’ll create your modules, functions, classes, and methods so that they model the way your domain experts think. By reflecting in code how users think and speak about their work, you refine your knowledge, expose gaps that would otherwise result in bugs, and create a malleable system that is responsive to the changes your users will want.

To continue the example, a program to typeset a musical score based on XML input could be designed around XML concepts. A better approach, though, might be to design it around domain concepts, as shown in Figure 12-1.

Code doesn’t leave room for ambiguity. This need for rigorous formalization results in more conversations and clarifies obscure details. I often see situations in which programmers run into a sticky design problem, ask their domain expert a question, and this in turn causes the domain experts to question some of their assumptions.

Two class diagrams. The one on the left is labelled “XML-centric design (simplified),” and it shows the relationships between an “Entity” and an “Attribute” class. The one on the right is labelled “Domain-centric design (simplified),” and it shows the relationships between domain-oriented classes, such as “Score,” “Measure,” “Staff,” and “Note.”
Figure 12-1. XML and domain-centric design

Your ubiquitous language, therefore, is a living language. It’s only as good as its ability to reflect reality. As you clarify points with your domain experts, encode what you’ve learned in your domain model. As the domain model reveals ambiguities, bring them back to your domain experts for clarification.

As you go, be sure that your design and the language you and your domain experts share remain in sync. Refactor the code when your understanding of the domain changes. If you don’t, you’ll end up with a mismatch between your design and reality, which will lead to ugly kludges and bugs.

Questions

Should we avoid the use of technical terms altogether? Our business domain doesn’t mention anything about GUI widgets or a database.

It’s okay to use technical language in areas that are unrelated to the domain. For example, it’s probably best to call a database connection a “connection” and a UI button a “button.”

How do we document our ubiquitous language?

Ideally, you encode your ubiquitous language in the actual design of your software using a domain model. If that’s not appropriate, you can document your model on a whiteboard (possibly a virtual whiteboard), shared document, or wiki page. Be careful, though: this sort of documentation requires a lot of attention to keep up-to-date.

The advantage of using code for documentation is that code can’t help but reflect what your software really does. With care, you can design your code to be self-documenting.

We program in English, but it’s not our first language, and our domain experts don’t use English. Should we translate their terms to English for consistency with the rest of our code?

It’s up to you. Words don’t always translate directly, so using your domain expert’s literal language is likely to result in fewer errors, especially if domain experts are able to overhear and contribute to programmers’ conversations. On the other hand, consistency might make it easier for others to work with your code in the future.

If you do decide to translate your domain experts’ terms to English (or another language), create a translation dictionary for the words you use, especially for words that don’t translate perfectly.

Prerequisites

If you don’t have any domain experts as part of your team, you may have trouble understanding the domain deeply enough to create a ubiquitous language. Attempting to do so is even more important in this situation, though. When you do have the opportunity to speak with a domain expert, the ubiquitous language will help you discover misunderstandings more quickly.

On the other hand, some problems are so technical that they don’t involve non-programmer domain knowledge at all. Compilers and web servers are examples of this category. If you’re building this sort of software, the language of programming is the language of the domain.

Some teams have no experience creating domain models and domain-centric designs. If this is true of your team, proceed with caution. Domain-centric designs require a shift in thinking that can be difficult. See the “Further Reading” section to get started, and consider hiring a coach to help you learn.

Alternatives and Experiments

It’s always a good idea to speak the language of your domain experts, but domain-centric design isn’t always the best choice. Sometimes a technology-centric design is simpler and easier. This is most often the case when your domain rules aren’t very complicated. Be careful, though: domain rules are often more complicated than they first appear, and technology-centric designs tend to have defects and high maintenance costs when that’s true. See [Fowler2002] for further discussion of this trade-off.

Another way to form a shared understanding of the domain is through Alberto Brandolini’s Event Storming, which starts with events that occur within the domain rather than the nouns and relationships of a domain model. At the time of this writing, the canonical Event Storming book was still being written, but https://www.eventstorming.com has pointers to further resources.

Further Reading

Domain-Driven Design: Tackling Complexity in the Heart of Software [Evans2003] is the definitive guide to creating domain-centric designs. Chapter 2, “Communication and the Use of Language,” was the inspiration for this practice.

Patterns of Enterprise Application Architecture [Fowler2002] has a good discussion of the trade-offs between domain models and other architectural approaches in chapter 2 (“Organizing Domain Logic”) and chapter 9 (“Domain Logic Patterns”).

5 Here’s an example of orchestral sheet music.