Concept · Architecture & domain modeling
Ubiquitous language
One shared vocabulary for developers and domain experts, used in conversation, documents and the code itself, inside a bounded context.
A ubiquitous language is a vocabulary that developers and domain experts build together and use everywhere — in meetings, tickets, documentation, tests, and the names of types, methods and tables. It's the foundation of domain-driven design (Eric Evans, 2003).
The problem it solves
Without one, every conversation needs translation. Operations says a driver "accepted a job"; the product spec says "booking confirmed"; the code has UpdateAssignment(status: 2); the analytics table says order_state = 'ACK'. Every translation is a chance to get a rule wrong, and new engineers must learn four vocabularies before they can fix a bug.
With a ubiquitous language, the business sentence "a driver accepts a booking, which becomes a trip when the passenger is picked up" maps directly to code:
func (b *Booking) Accept(driver DriverID, at time.Time) error
func (b *Booking) PickUp(at time.Time) (Trip, error)Domain experts can read the method names in a code review and tell you if a rule is wrong.
Building it
- Listen to how experts talk, and adopt their words — not database jargon or framework terms.
- Make implicit concepts explicit. If people keep saying "a cancellation after the driver arrives" and it has its own fee, it deserves a name and a type.
- Run event-storming workshops: put every business event ("Booking requested", "Driver arrived", "Payment captured") on sticky notes along a timeline, and argue about names and meanings until everyone agrees.
- Keep a glossary close to the code.
- Refactor when the language changes. If the business renames "booking" to "order", rename the code too. A mismatch left in place becomes a permanent translation tax.
Scope
A ubiquitous language is only consistent within one bounded context. "Order" in billing and "order" in delivery mean different things, and forcing one definition on both creates confusion. Each context gets its own language, and the boundary is where translation happens. See the domain-driven design lesson.