How to build a ubiquitous language
Insight
The language you use in the code and the artefacts should be the same language that you agree upon with the business
“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.”
Eric Evans in Domain-Driven Design: Tackling Complexity in the Heart of Software.
In any team or department, a shared social language that works for them will evolve. This language is very organic and always in motion. It’s messy and often ambiguous, with words shifting meaning over time. The team will use different words for the same thing or use different words to mean more or less the same thing. All this is very normal; that’s how natural language works, and our brains are very good at dealing with this ambiguity.
But the language needs to be precise and unambiguous when we get to system design. The nature of software tells us whether our language is wrong or not. A misspelling or a forgotten comma will break the build. In Domain-Driven Design we say that the language you use in the code and the artefacts should be the same language that you agree upon with the business. Instead of choosing the domain language, which is too messy and evolving, or the language of the developers which can be too esoteric, we use an agreed-upon language to talk in unambiguous terms. This is a language that has been deliberately designed, based on the domain, between the engineering and business stakeholders. This language is tightly coupled with individual Bounded Contexts, meaning the language we use to describe things in one bounded context might differ from another.
It takes deliberate effort from the team to find the right words. The very act of naming is often an overlooked part of software design. When we persist with using new names in diagrams, conversations, and code, we can iron out ambiguity and misunderstandings and, therefore, build a better model and, by extension, a more coherent and performant system.
What vocabulary should be agreed upon?
Eric Evans’ who termed and popularised Domain-Driven Design in his book, “Domain-Driven Design” says the ubiquitous language should name the core elements related to the model and system you’re building. These include:
Classes, Types and prominent operations
Terms to discuss rules that have been made explicit in the model
Terms from high-level organising principles imposed on the model
Names of patterns the team commonly applies to the model
How formal should this language be?
The formality of the language depends on your context. If you're a fast-moving startup, formal might mean a quick discussion during domain discovery to agree on key terms. If you are in a life-critical domain like medical devices, formal might mean following a strict RFC process which is strictly implemented. If you are tasked with writing the next version of the HTTP specification, formal is something that will be considered the one way to do things for the next 100+ years.
Formality is contextual, but it's always more formal than the daily language that people in the domain use. If the language evolves, we should co-evolve the ubiquitous language in our code and models, documentation, tests, and so on.
When should you start developing a ubiquitous language?
A ubiquitous language often emerges during collaborative domain modelling. You can’t model without having some agreement on language, otherwise you just have a drawing and words without meaning. In the process of modelling, key terminology and the naming of sequences are clarified and agreed upon. The language and model are therefore very tightly connected. When we define something new, we will define it in relation to other things in the domain or the model.
A simple example would be to look at designing an e-commerce platform. If an “Order” consists of a list of “Products” and “Quantities”, that's a model, because we say there's a relationship between the “Order” and the “Product”. But we also need to understand what the “Product” is to define an “Order”. It doesn't make sense to say an “Order” is a list of “Products” without knowing what the “Product” is. The language will always be defined in terms of the model, and the relationship between these things describes the model.
Teams should work on clarifying language early on in the design process to diffuse misunderstandings between engineering and business stakeholders to build more coherent software.
In summary, when the Ubiquitous Language is used well, a non-technical domain expert could read the code and understand what it does. But even without going that far, this shared language makes communication about the software much smoother, so that the resulting software is much more aligned with the business needs.