Don’t abdicate the ubiquitous language

The Ubiquitous Language of Domain Driven Design is a call for developers and domain experts to communicate openly, instead of erecting false barriers of obfuscation. It admonishes developers not to put pattern names or technical terms into the domain model.

Yet it also does not suggest that developers should abdicate the language to the domain experts. Imprecise language cannot be tolerated. When a domain expert uses it, it is the developers' duty to correct it.

The following four-letter words are indicators of imprecise language:

  • Type
  • State/Status
  • Code
  • Text

When a domain expert uses the term "type", they are trying to classify objects in a meaningful way. Work items, for example, can either be bugs or enhancements. Orders can be purchase orders, quotes, or returns.

Domain experts will often model type as an attribute of a single entity. The behavior of that entity is sometimes dependent upon this "type" attribute. Entities of one type are treated differently than entities of another type, but only in certain situations. Pricing is run on purchase orders and quotes, for example, but not on returns.

When a developer sees the word "type", they immediately attach some assumptions to it. An entity can only be an instance of one concrete type. Its type is determined at the time of creation and cannot change during its lifetime. Type determines the attributes and behaviors of the object. These are not the assumptions that the domain expert means to imply. A work item may be entered as a bug, but later determined to be an enhancement. The work item type can change. If we modeled this domain using a static type system, such a change would be impossible.

It would be more useful to identify the reason that objects have different "types". A work item is either a bug or an enhancement because of the feature set it affects: existing features or new features. Orders are purchase orders, quotes, or returns because of their intent. Let's use the more precise terms "feature set" and "intent", and not the overloaded term "type" to represent these attributes of an entity.

State and Status
When a domain expert uses the term "state" or "status", they are trying to express a workflow. A work item is in the "new", "fixed", or "closed" state. An order status can be "received", "processed", or "shipped".

State and status are modeled as attributes of an entity. But they are in truth events in the workflow. As an entity moves through a workflow, the intent is not so much to modify that entity. Rather, it is to gather information about the entity. This is a concept discussed by Greg Young in Unshackle Your Domain. The events should themselves be part of the domain model.

States are only meaningful within a context. But entities are often found at the intersection of several contexts. An entity can be in several states simultaneously, depending upon what question is being asked. But if "state" is an attribute of an entity, it can have only one value. This can lead to a combinatorial explosion of states that attempt to simultaneously represent two or more contexts.

It would be more useful to identify the events that can occur within a workflow, and ask questions in terms of that history.

When a domain expert uses the term "code", they are usually calling out an implementation detail about how a problem is currently solved. Our ordering system currently has a "signal code" attached to a product. This three-letter code is used to signal the system that special processing needs to take place.

For example, one signal code indicates that the product is a controlled substance, and therefore requires DEA license validation. Another signal code indicates that the product is drop shipped, so different inventory behavior is applied.

The problem with codes is that they are already entrenched. It is hard to convince a domain expert that there is a problem. Telling them that codes represent different dimensions is too abstract. But if you give them a concrete example, they already have an answer for it.

"What if a product is both a controlled substance and drop shipped?"

"Are you crazy! We don't drop ship controlled substances!"

It would be more useful to identify the dimensions along which entities vary and make those independent attributes. A product has licensing requirements, and also has an inventory strategy. Interactions among those various dimensions can be captured as business rules.

Unless the domain is specifically about books, the term "text" is often used to represent a note to be displayed in a specific place. A customer service representative can enter "footer text" when placing an order, which appears on the footer of the invoice.

These notes are important to capture, as the primary purpose of any system is to facilitate communication among its users. But the notes should be named according to their purpose, not according to where they appear. Formats change over time, and are not an appropriate concept for the domain model. Our "footer text" for example no longer appears on the footer of the invoice. It would be more useful to call it "invoice instructions".

The four-letter words listed here are just the most egregious examples of imprecise language. There are many other examples that could be cited. As a developer, it is your job to ask questions when you see them. You need more information about what these terms mean in context. If you have to ask a domain expert to elaborate, then they have not chosen a precise term. Once they do elaborate, suggest that they use that term instead.

Leave a Reply

You must be logged in to post a comment.