Adopting a Ubiquitous Language for Your App

We recently starting consulting for a medium-sized software company whose codebase was in the middle of a big pivot. One of the first observations we made during our onboarding was that developers, designers, and product owners were using different terms to refer to the same things. For example, where a designer may have referred to a “widget,” a developer would call the same thing a “utility.” When a product owner asked about the “data stream,” the developer would translate that to “profile API” in her head.

What the team needed was one ubiquitous language. Ubiquitous language (UL from here on out) is a core tenet of domain-driven design. In short, it’s a vocabulary describing the software domain that all team members agree to use consistently. So if the team has decided to refer to a particular API as “the data stream,” each team member–developer or otherwise–must use that term in all aspects of the software development process.

UL is particularly important when working as part of a team. In The Art of Agile, James Shore explains that UL reduces miscommunication because the terminology is equally accessible to all parties. He cites an example in which a team is writing software that renders musical notation from XML data. Instead of asking the product owner about how to render specific XML edge cases, the programmer must use the agreed-upon UL–which likely includes terms like “octave” and “clef,” not XML-specific terms like “child” and “attribute.” From the other side, it’s the product owner’s responsibility to refer to the technical aspects of the app correctly; he may need to use the term “login view” when his initial inclination would be to say “login portal.”

This UL is not only verbal. It’s important to extend this consistency into the source code itself. (Some would go so far as to say this is the most important aspect of a UL). Inconsistent terminology in source code leads to duplication and bugs, and makes it hard to onboard new developers. From a practical standpoint, developers should name variables and classes from the UL. This makes it easier for a developer to ask questions and solicit feedback from the product owner. The dev no longer needs to first translate the terminology before speaking up.

It doesn't take too much effort to get UL going within your team. First, you need to hold a meeting (or circulate a document) defining all the terms in your UL. Needle the differences between words like “beta” and “pre-release,” “login” and “authenticate”, and whatever is specific to your domain. Then, hold your team members accountable when they stray from the agreed-upon UL. As the project evolves and terms change, keep your UL document up-to-date, and change any outdated references in source code.

For much more on Domain-Driven Design, check out QLer Mike’s engineering lunch presentation, Confidently Build Complex Domains in Rails.