Domain-Driven Design (DDD)
An approach to modeling complex software around the business domain and its real language — bounded contexts, ubiquitous language. Its value is in the hard domains.
What is Domain-Driven Design?
Domain-Driven Design (DDD), introduced by Eric Evans, is an approach to building software for complex business domains by modeling the software around the domain itself — its concepts, rules, and the real language domain experts use. Rather than starting from database tables or technical layers, DDD starts from a deep, collaborative understanding of the business problem and encodes that understanding directly into the code’s structure and vocabulary. It’s less a set of tools than a philosophy about where complexity should live and how to tame it.
The ideas that actually matter
Two DDD concepts have outlived the rest and shape modern architecture. Ubiquitous language: developers and domain experts share one precise vocabulary, used identically in conversation and in code — if the business says “policy,” the code says Policy, not Record — eliminating the translation errors that creep in when engineers invent their own terms. Bounded context: a domain is split into distinct contexts, each with its own model and its own consistent meaning for terms, with explicit boundaries and translation between them. This is DDD’s most influential idea because it maps almost directly onto microservices: a well-drawn bounded context is often exactly the right boundary for a service, which is why DDD became foundational to service decomposition. Get the contexts wrong and you get distributed-monolith pain — services that can’t change independently because their models bleed into each other. Tactical patterns (aggregates, entities, value objects, repositories) fill in the how, but strategic design — contexts and language — is where the leverage is.
When to use it — and the honest caveat
DDD’s whole premise is complex domains. Its investment — deep domain modeling, close collaboration with experts, careful boundary-drawing — pays off when the business logic is genuinely intricate (insurance, logistics, finance, healthcare), where the cost of misunderstanding the domain is high. For simple, data-centric applications — CRUD over a handful of entities, thin business rules — full DDD is heavy machinery for a light job, and its ceremony can slow a team down for no benefit. The pragmatic reading: adopt DDD’s strategic ideas (ubiquitous language, bounded contexts) widely because they’re cheap and clarifying, and reserve the tactical patterns for the genuinely complex cores of your system. It complements CQRS and event-driven designs, which often emerge naturally from good context boundaries.
What people get wrong
- Applying full tactical DDD to simple CRUD — the ceremony (aggregates, value objects, repositories) is overhead where the domain is thin.
- Skipping the language discipline: without a shared ubiquitous language, code and domain experts drift apart and requirements get lost in translation.
- Bad context boundaries — drawing bounded contexts wrong produces microservices that can’t evolve independently: a distributed monolith.
Primary source: Martin Fowler: Domain-Driven Design
Historical figures and technical concepts for informational purposes only. Not technical, professional, legal, or financial advice. Sources: Official Documentation.