Skip to content

08 · Make the implicit explicit

When you finish this lesson you should be able to:

  • Hunt implicit concepts using Evans’s sources: language, awkward design, expert contradictions, domain literature, experiments
  • Turn a report line-item into an object when it is actually a concept
  • Model policies, specifications, and processes instead of boolean soup
  • Recognize a breakthrough as a cascade, not a rewrite ticket

Building blocks get a model that runs. It is still usually shallow. Meaning hides in:

  • a line on a report assembled from three tables
  • a nightly job nobody can explain
  • a comment: “don’t send if bucket < 10”
  • two experts who disagree and a developer who averages them in an if

Deep models appear when those things get names and a place in the language. Evans calls the sudden version of this a breakthrough: the discussion changes quality; experts correct details instead of waving; several hacks collapse.

You cannot put “breakthrough” on the sprint board. You can put the hunt.

Listen to language. Users have always talked about an item on a report. You assembled it from attributes and a query in two places. You never made an object. Then it clicks: that name is a domain concept. You draw. They correct connections. The conversation gets precise. That object was implicit in the report all along.

Scrutinize awkwardness. When every feature needs a six-way if, the missing noun is in the middle of the if.

Contradictions. “Holdout never moves” vs “holdout should follow the experiment.” That is two concepts (holdout policy vs experiment salt), not one boolean.

Literature of the domain. Lending, accounting, and logistics already have names (see lesson 10). Do not be proud of inventing a worse word.

Lots of experimentation. Try the name in code for a week. If nobody speaks it, kill it.

  • Constraints as objects: “never double-notify this failure” → identity of a Delivery / Receipt, not sent_flag.
  • Processes as objects: Onboarding as something with allowed transitions, not onboarding_step plus hope.
  • Specifications: a named predicate, IsEligibleForPlan, composable, testable, discussable with experts.
  • Policies: Strategy in domain clothes (lesson 10)—QuietHours, Holdout, RetryPolicy.

One name simplifies three features. After Holdout exists, kill switch, reporting, and ethics review stop colliding with “the bucket.” After Delivery exists, email and push retry stop living in the thread aggregate.

Epilogue in Evans: insight cascades. Your job after a breakthrough is to follow it through the code, not to bank the metaphor and move to the next ticket.

Implicit:

if (hash(userId) % 100 < 10) return;

Meeting word: holdout. Explicit:

function inHoldout(policy, userContext) {
return hash(userContext.id, policy.holdoutSalt) < policy.holdoutPercent;
}

Product can say “raise holdout to 5%.” You change a value.

Second implicit: worker retries send two “card failed” mails. Explicit: Delivery with idempotency = deliveryId. The expert sentence is “we already notified this failure.”

  1. Three ifs from a real or invented onboarding/messaging path.
  2. Expert sentence for each.
  3. Name: entity, value, spec, or policy?
  4. Rewrite one if as a call.
  5. Two other features that get simpler. If you cannot name any, the concept is still too local—keep digging or kill the name.
  • Domain-Driven Design — Chapter 8, Breakthrough
  • Domain-Driven Design — Chapter 9, Making Implicit Concepts Explicit