Skip to main content

Domain-Driven Design (DDD)

Domain-Driven Design models complex business domains in code using a shared ubiquitous language and bounded contexts, aligning software structure with the business. It tames domain complexity and provides natural seams for decomposing systems into services.

Organization
Eric Evans
Published
Aug 30, 2003

Best Practice: Domain-Driven Design (DDD)

Domain-Driven Design is an approach to building software for complex business problems by putting the business domain at the center of the design. Introduced by Eric Evans in his 2003 book, DDD insists that developers and domain experts share a single ubiquitous language that appears in conversation, documentation, and the code itself. It divides a large domain into bounded contexts, each with its own consistent model and clear boundaries, so different parts of the business are not forced into one tangled model. DDD matters because the hardest part of large systems is managing domain complexity, and aligning software structure with the business makes systems easier to understand, change, and decompose into services.

Step-by-Step Implementation Guidance

  1. Immerse in the domain with experts to learn the real business problem.
  2. Build a ubiquitous language and use those exact terms in the code.
  3. Identify bounded contexts where a model stays consistent, and draw their boundaries.
  4. Map relationships between contexts with a context map.
  5. Model within each context using building blocks: entities, value objects, aggregates, and domain events.
  6. Protect invariants by keeping changes within aggregate boundaries.
  7. Revisit the model continuously as understanding of the domain deepens.

Common Mistakes Teams Make When Ignoring This Practice

  • Building one shared model for the whole business that nobody fully understands.
  • Using technical jargon that does not match how the business actually talks.
  • Ignoring bounded contexts, so unrelated concepts collide in one model.
  • Applying heavy DDD tactics to simple, non-complex domains.
  • Treating the model as fixed instead of refining it as the domain is understood.

Tools and Techniques That Support This Practice

  • Event Storming workshops for collaborative domain discovery.
  • Context mapping to document relationships between contexts.
  • Aggregate and value-object patterns in code.
  • Hexagonal Architecture to keep the domain model isolated.

How This Practice Applies to Different Migration Types

  • Cloud Migration: Use bounded contexts to decide which capabilities move to the cloud first.
  • Database Migration: Align new schemas with aggregate boundaries rather than legacy table sprawl.
  • SaaS Migration: Map which bounded contexts a SaaS product can replace versus those you must keep.
  • Codebase Migration: Use bounded contexts as the natural seams for splitting a monolith into services.

Checklist

  • Engage domain experts to understand the real problem.
  • Establish a ubiquitous language used in the code.
  • Identify and bound your contexts.
  • Produce a context map of their relationships.
  • Model with entities, value objects, and aggregates.
  • Keep invariants inside aggregate boundaries.
  • Refine the model as domain understanding grows.