Skip to content

07 · Model out loud

When you finish this lesson you should be able to:

  • Speak about the product in words a domain expert would recognize
  • Separate identity (entity) from measured-by-value (value object)
  • Catch when your code names and your spoken names have drifted

If you say “record,” “object,” and “manager” while the product people say “assignment,” “audience,” and “holdout,” you are translating in your head on every sentence. That tax shows up as missed cases.

A ubiquitous language is the same set of words in conversation, on the whiteboard, and in the types. You model out loud: “an Assignment is this user, this flag, this Variation, for this Experiment.” If someone uses a word two ways, stop and pick.

In software:

  • Entity — has identity that remains as its attributes change. User, Experiment, InboxThread. Equality is “same id.”
  • Value object — measured by its attributes. Money, QuietHours, PercentRollout. Immutable in practice; replace rather than mutate.
  • Service — a verb that is not a natural thing to hang on one entity. AssignVariation, RouteChannel. Keep these thin; if a service becomes a dumping ground, a concept is still implicit.

Isolating the domain means the model is not the HTTP handler and not the table shape. The handler translates. The table stores. The model is where the words live.

You do not need a 400-page process to do this in an hour. You need to refuse mushy nouns and to say when two boxes are the same idea with two names.

Feature flags, spoken badly: “the thing,” “the config,” “the JSON,” “the user hash.”

Spoken as a model:

  • Experiment (entity): id, hypothesis, running window.
  • Variation (value): key control | treatment, maybe payload.
  • Audience (value): rules over a UserContext.
  • Assignment (entity if you persist and audit it; value if it is a pure function of user + experiment + salt).

That last sentence is a real modeling choice. If legal needs “what did we show this person last Tuesday,” Assignment is an entity with history. If you can always recompute from salt and you do not care about past bugs, it is a value. Say the choice; do not hide it in a Map.

function assignmentOf(experiment, userContext, salt) {
const variation = pickVariation(experiment, userContext, salt);
return { experimentId: experiment.id, userId: userContext.id, variation };
}

The names in the function are the language. If you would not say pickVariation at the whiteboard, rename it.

Talk, then three types on paper.

  1. Domain: first-run onboarding (account, verify, plan, first session).
  2. For two minutes, only allowed words are product words. No “manager,” “helper,” “util.”
  3. List entities vs values. If you are unsure, say why.
  4. Write one sentence invariant (“a session cannot enter FirstSession before Identity is verified”).
  5. Rename any leftover mushy word.
  • Domain-Driven Design — Chapter 2, Communication and the Use of Language
  • Domain-Driven Design — Chapter 5, A Model Expressed in Software