Domain-Driven Design

9 min read · Updated 2026-04-25

Domain-Driven Design (DDD) is a systematic approach to analyzing complex business problems and modeling software solutions. It splits naturally into two complementary halves: strategic design (the big-picture boundaries) and tactical design (the building blocks inside each boundary).

Two Spaces

DDD constantly distinguishes between the problem space (the business reality you’re modeling) and the solution space (the architecture that addresses it).

Problem space
What needs solving
The business domain itself, independent of software. Domains, sub-domains (core / supporting / generic), and the language the business actually uses.
Solution space
How we structure software
Bounded contexts, context maps, integration patterns. The architectural shapes that reflect the problem space.

Inside the problem space

Domain
The whole business area you operate in.
Sub-domains
Logical divisions of the domain — by business capability.
Core domain
The differentiating capabilities unique to your business.
Supporting sub-domain
Necessary, but not differentiating.
Generic sub-domain
Cross-cutting concerns; not unique to your business.
Ubiquitous language
The shared vocabulary that bridges business and engineering.

Inside the solution space

The Bridge: One Domain, Many Models

The same business concept can carry different meanings across bounded contexts — and that’s a feature, not a bug.

The model is what spans both spaces. Multiple bounded contexts can reference the same sub-domain; one sub-domain can be touched by multiple bounded contexts. The relationships are many-to-many.

Tactical Building Blocks

Inside a bounded context, tactical DDD gives you the patterns to express the model in code.

Entities
Objects with unique identity that persist over time (Customer, Order).
Value objects
Defined by their attributes, not identity (Address, Money).
Aggregates
Clusters of entities and value objects treated as a single unit for state changes.
Aggregate root
The single entity in an aggregate that external code can reference directly.
Domain services
Operations that don't naturally belong to a single entity or value object.
Repositories
Abstractions for storing and retrieving aggregates.
Factories
Encapsulate the logic for constructing complex aggregates.
Domain events
Significant occurrences in the domain that other parts of the system care about.

A Concrete Walkthrough

Imagine an e-commerce platform. Strategic analysis surfaces three sub-domains:

Each maps to a bounded context. Inside the Order Processing context, tactical patterns shape the model:

Strategic and Tactical Are Iterative

Strategic and tactical design are not sequential phases. You start with strategic analysis to find boundaries, but tactical implementation insights routinely feed back into strategic refinement. The boundary that looked clean on a whiteboard sometimes turns out to be wrong; the fix is to redraw the boundary, not paper over it in code.

The domain model emerges from this iteration — from the dialogue between business reality and software implementation.

Why DDD Pays Off

DDD does three things at once that no other approach quite does:

  1. Aligns software structure with business structure. What changes in the business changes in the same place in code.
  2. Gives engineers a shared vocabulary with the business. No translation layer between requirements and design.
  3. Provides patterns for the gnarly bits — invariants across multiple entities, integrating with legacy systems, evolving boundaries as understanding grows.

In multi-tenant SaaS, where the product and the business model are tightly coupled, DDD is often the difference between a platform that scales coherently and one that becomes the kind of “big ball of mud” the previous lesson warned about.

Recap