Module 3: Domain-Driven Design & Bounded Contexts: Worked Examples
Example 1: One Word, Two Models
Sales uses “customer” for a prospect or buyer with offers and credit terms. Support uses “customer” for an account entitled to service. A shared Customer entity accumulates nullable fields and conflicting lifecycle rules.
Wrong attempt. Create one enterprise model so terminology is “consistent.” It erases useful differences and couples releases.
Correct reasoning. Define Sales and Support bounded contexts with their own models and ubiquitous language. Map identities through an explicit contract. Consistency means each term is precise inside its context, not identical everywhere.
Example 2: Find an Aggregate Boundary
An order aggregate must preserve “accepted total equals the sum of accepted lines” in one transaction. Inventory availability belongs to another consistency boundary and is confirmed asynchronously. Putting product catalog, inventory, payment, and shipment inside one aggregate creates contention and a distributed transaction disguised as an object graph.
Rule. Include only state required to enforce an immediate invariant. Coordinate other outcomes with commands/events and explicit failure handling.
Example 3: Protect a Model With an Anti-Corruption Layer
A legacy ERP exposes CUST_STAT=7 and mutable invoice records. Translate them at the boundary into domain concepts such as AccountSuspended and immutable invoice snapshots. Keep ERP vocabulary and failure semantics out of the core model.
Completion Standard
- Produce a context map with relationship types and ownership.
- Define aggregate invariants and transaction boundaries.
- Demonstrate translation tests for one anti-corruption layer.