Teams often don’t pay enough attention to language.
A team can improve its language by using what Eric Evans calls Ubiquitous Language: “A language structured around the domain model and used by all team members to connect all the activities of the team with the software.” (Domain-Driven Design, p. 514)
Let’s see how the domain vocabulary and ideas can be used at multiple levels.
Level 1: User Stories
Different people write user stories in different ways.
Some people frame stories in the solution domain:
User clicks the blue button to get a status email
(or “As a user, I want to click…”).
Other stories focus on the problem domain (i.e., domain model):
User requests package status
or
System notifies user of package status
or perhaps
System emails user about package status
I prefer the domain-model style for a few reasons:
- The domain-model style links to the user’s goals. People go around wanting to know the status of their package, but relatively few have a desire to click blue buttons.
- The domain-model style allows for a variety of solutions. This makes it more reusable, as it depends less on particular technology.
- Using the same terms that customers use helps the whole team understand the user’s model of what the system is doing.
Level 2: Testing
There are many different kinds of tests, and different tests have different goals.
One type of test centers around examples. Whether you call it BDD (Behavior-Driven Development), ATDD (Acceptance-Test Driven Development), Example-Driven Development, customer tests, or whatever, you have a choice about the level of discourse.
Play-by-play style depends on the user interface and details of exactly how the system works:
Given the user is on the home page And the user enters "Aretha - Complete CD Collection" in the search box And the user hits return And the user clicks the first item And the user clicks "Add to Cart" When the user clicks "Immediate Purchase" Then the item is ordered And the user returns to the home page When the user clicks the blue "Track My Package" button Then the system displays "Your tracking info will be in your email." When the user opens their email system And the user waits 10 minutes And the user clicks "Refresh" Then the user sees the tracking email
Painful, huh?
- There’s no abstraction – everything is a series of low-level moves, and it’s hard to get a sense of what the user is actually trying to accomplish. (Are we testing search, purchase, tracking, all of them at once, or what?)
- The test depends on details of the user interface, and that’s the part most likely to change. That makes the tests brittle.
In contrast, you can write a better test – at a higher level, using the problem domain’s language, more focused:
Given a returning customer has ordered "Aretha - Complete CD Collection" When the customer requests tracking Then the system displays "Your tracking info will be in your email." And the customer receives a tracking email
Level 3: The Code
Solution language will certainly show up in the code.
But good code usually uses the domain vocabulary extensively.
However, if the programmer is forever talking about p-items, it may take others a while to realize that it’s meant to be the same as packages, and it may be even harder to notice subtle differences.
The computer doesn’t care what we call things. We name them so that we get the benefit of easier communication.
In our example, package, status, and email are all domain terms.
If we use domain terms consistently in our code, the same way that users, product people, and testers use them, we make it easier to ensure that code, tests, stories, and product and user perception are aligned.
A common vocabulary – shared across the whole project community – enables better conversations and better understanding.
Conclusion – Ubiquitous Language
Finally, I’ll close with one more observation from Eric Evans:
“The more pervasively the language is used, the more smoothly understanding will flow.” – Domain-Driven Design, p. 25