Domain-Driven Design.
An approach to software development that centers the design on a rich model of the business domain, expressed in a language shared by engineers and domain experts.
##Intent
Tackle complexity in the heart of software by modeling the business domain explicitly, and by keeping that model — and the code that expresses it — in tight alignment with the language used by the people who understand the domain.
##Problem
As a system grows, business rules tend to scatter across controllers, services and database queries. The code drifts away from how the business actually talks about its work, so every conversation needs translation and every change risks breaking a rule nobody remembered.
Data-centric designs make this worse: models become anemic bags of getters and setters, invariants live nowhere in particular, and the system slowly turns into a "big ball of mud" that only a few people dare to touch.
##Solution
Domain-Driven Design attacks the problem on two levels.
Strategic design divides a large domain into bounded contexts — explicit boundaries within which a model and its language are consistent — and maps the relationships between them. Each context is free to model the same concept differently where the business genuinely sees it differently.
Tactical design builds a rich model inside a context from a small set of building blocks, and insists on a ubiquitous language: the same terms appear in conversations, in the model and in the code.
##Structure
The tactical building blocks:
- Entities — objects defined by identity that persists over time (a
Customer, anOrder). - Value objects — immutable objects defined by their attributes (a
Money, anAddress). - Aggregates — clusters of entities and value objects with a single aggregate root that guards the cluster’s invariants and is the only entry point for changes.
- Repositories — collection-like interfaces that load and persist whole aggregates, hiding storage details.
- Domain services — stateless operations that don’t naturally belong to a single entity.
- Domain events — records of something meaningful that happened in the domain.
The strategic blocks — bounded context and context map — organize these models across teams and subsystems.
##Applicability
- Use it when the core complexity is in the business rules, not the technology — logistics, finance, insurance, scheduling.
- Use it when several teams must agree on a shared, evolving understanding of a domain.
- Avoid it for simple CRUD or data-entry applications, where the modeling overhead buys you little.
##How to Implement
- Talk to domain experts and distill the ubiquitous language; write down the terms and what they mean.
- Identify the core domain — the part that gives competitive advantage — and focus modeling effort there.
- Carve the domain into bounded contexts and draw a context map of their relationships.
- Within a context, model aggregates so that each one enforces its own invariants in one transaction.
- Load and save aggregates through repositories; publish domain events for things other contexts care about.
- Refine continuously — the model is never “done,” it evolves as understanding deepens.
##Pros & Cons
- Keeps code aligned with the business, so changes map cleanly to requirements.
- Isolates complexity behind bounded contexts.
- A shared language reduces miscommunication between engineers and experts.
- Rich domain logic is decoupled from infrastructure and easy to unit-test.
- Steep learning curve and a real investment in domain modeling.
- Overkill for simple or mostly-CRUD applications.
- Requires ongoing access to domain experts.
- Misapplied, the building blocks become ceremony without benefit.