DDD — Domain-Driven Design
npx machina-cli add skill bofrese/bob/ddd --openclawDDD — Domain-Driven Design
A thinking framework. Apply when decomposing a problem, naming things, or deciding where code belongs.
The core discipline
Let the domain drive the design. The structure of the code should mirror the structure of the problem, not the structure of the database or the UI.
Bounded contexts
A bounded context is a part of the system where a specific model applies — and where terms have precise, agreed meanings. Outside that context, the same word might mean something different.
- Identify the boundaries before you name things.
- Within a boundary: one model, one vocabulary, one source of truth.
- Across boundaries: translate explicitly. Don't let one context's internals leak into another.
Ubiquitous language
Within a bounded context, everyone — developers, product people, the code — uses the same words for the same things.
- Name your code the way the domain names the concept. Not the way the database column is named.
- If a concept doesn't have a domain name, find one before you code it. Forcing domain language on the code is one of the highest-value acts in a codebase.
Model reflects the domain, not the database
- The domain model is the source of truth. The database is a persistence detail.
- If your model class looks like a table schema — flat rows with foreign key fields — you haven't modelled the domain. You've modelled the storage.
- Ask: "Does this structure make sense if I explain it to someone who understands the problem but not the tech?"
The golden check
Before committing: does the code read like a conversation about the problem? If someone unfamiliar with the internals can follow the domain logic by reading the names alone, the design is working.
Overview
DDD helps you shape software by letting the domain drive the design. It emphasizes bounded contexts, ubiquitous language, and modeling that reflects the problem rather than storage details. This approach supports clearer responsibilities during feature ideation and architectural planning.
How This Skill Works
Start with the domain and subdomains, define bounded contexts with precise terms, and establish a ubiquitous language. Model in code to reflect the domain, not database schemas, and keep each context isolated with explicit translation points across boundaries.
When to Use It
- When decomposing a problem into modular boundaries
- When naming classes, services, and aggregates to match domain concepts
- When deciding where code belongs across a complex system
- During feature ideation and architectural planning to align with domain concepts
- When integrating multiple subsystems to prevent leakage of internal details
Quick Start
- Step 1: Map the domain and identify bounded contexts
- Step 2: Define the ubiquitous language for each context and align your code
- Step 3: Model with boundaries in mind and plan cross-context translations
Best Practices
- Start from the domain, not the database or UI
- Define bounded contexts with clear boundaries and one model
- Establish a ubiquitous language in code and conversations
- Use explicit translation when crossing context boundaries
- Continuously refactor to keep the domain model the source of truth
Example Use Cases
- Split an e-commerce domain into Orders, Payments, and Inventory bounded contexts
- Name classes using domain terms like CustomerProfile rather than database field names
- Translate user stories into bounded contexts before coding
- Refactor a monolith by mapping modules to bounded contexts
- Apply the golden check: code reads like a conversation about the problem