Skip to content

02 · Ubiquitous language

When you finish this lesson you should be able to:

  • Hear a conversation split into “business talk” and “tech talk” and reconnect it
  • Model out loud until a sentence can be a test name
  • Use diagrams as speech, not as a second unpublished language
  • Know when two meanings of the same word mean two contexts (lesson 12), not a bigger glossary

Evans’s claim is stronger than “name things well.” The domain model is a set of concepts in people’s heads, with terms and relationships that carry meaning. That language has to be precise enough to develop with, and it has to show up in every medium: conversation, informal diagrams, written notes, tests, and the code.

UML is optional. Pervading communication is not.

If the language is weak, you get Evans’s cargo-router smell (his dialogue in this chapter): the user speaks business change (“customs clearance point”), the developer answers in tables and delete-rows. Nobody can check that the software means the right thing. A stronger language lets both people talk about Cargo, Route, Leg—or in our product, Assignment, Holdout, Experiment—and disagree about rules instead of about SQL.

  • Experts use field jargon, often in several dialects (“verified” in support ≠ “verified” in risk).
  • Developers talk about the system functionally (“we TTL the blob”) or invent abstractions experts cannot hear.
  • Different parts of the team grow private dialects. After six months you have four ubiquitous languages and none of them are ubiquitous.

The project does not magically pick one. You experiment with language the same way you experiment with the model. Try a word in a meeting. If experts flinch, rename. If developers cannot implement it, the word is still mush.

Speak in types. “The Assignment is stale when the Experiment’s salt rotates” is a model sentence. “We bust the Redis key on config push” is an infrastructure sentence. You need both jobs; only one belongs in the ubiquitous language.

Tests are speech. assignment_is_stale_after_salt_rotation is how the language survives a refactor. If your tests say testProcess1, the language is already dead in the only place that is executable.

Code is speech. rotateSalt on Experiment is better than updateConfig(json). A new hire should learn the business from the domain module.

Inside this team, this model: one language. Across the company: lesson 12. Forcing Finance’s Account and Identity’s Account into one word is how you get a 200-column table and meetings that never end.

A glossary can onboard people. A glossary that is not the code will rot. Prefer types.

Evans is not anti-documentation. He is anti disconnected documentation.

  • Explanatory models teach a hard idea (a picture of holdout vs assignment). They may simplify. Label them as explanation.
  • The model you implement uses the same names as the repo. If the diagram has nouns the code does not, someone is performing.

Agile’s informal diagrams work because they are speech in the ubiquitous language, erased and redrawn. A 40-class wall that nobody can walk through a scenario with is costume.

Thin language

P: When we change the experiment JSON, some users still see the old variant.
D: Yeah the edge cache has a five-minute TTL on the config blob.

Nothing here can be tested as a rule. You might “fix” the wrong thing (TTL) while the real bug is “Assignment is computed from an old salt.”

Ubiquitous language

P: Changing an Experiment’s salt should invalidate Assignments.
D: Serving recomputes Assignment from UserContext and the new salt. Holdout uses a different salt so it does not move with the experiment.

Now you can write two tests and a type. Product can argue about whether holdout should move. That argument is the work.

Homonyms to split: User (login) vs UserContext (targeting attributes). Account (identity) vs Account (billing). If you keep one class, you will pass passwords into an experiment hasher.

  1. When someone says “the thing,” stop and name it.
  2. When two people use the same word differently, write both definitions. Do not average them.
  3. When you hear a new verb (“snooze,” “float,” “claw back”), ask if it is a command on an existing entity or a missing concept.
  4. After the meeting, rename one type the same day. Language that waits for a “cleanup sprint” never lands.
  1. Record (or reconstruct) five lines of a real design chat.
  2. Highlight every infrastructure word. Rewrite without them, using only domain nouns and verbs. Ban manager, util, row, JSON, cache, TTL.
  3. List words you needed that are not types today.
  4. Write two test names in the language.
  5. If a word has two definitions, you just found a bounded-context candidate. Park it for lesson 12; do not merge the definitions.
  • Domain-Driven Design — Chapter 2, Communication and the Use of Language (ubiquitous language; modeling out loud; one team; documents, diagrams, explanatory models)