Domain Driven Design (DDD) is an approach to software development that emphasizes modeling the problem domain and using that model to drive design decisions.
Core Principles
Ubiquitous Language
- Shared language between developers and domain experts
- Same terms used in code, conversations, and documentation
- Reduces translation errors and miscommunication
Bounded Contexts
- Explicit boundaries where a model applies
- Each context has its own ubiquitous language
- Different contexts can have different models of same concepts
Domain Model Purity
- Separate representation from identity
- Keep domain logic free from infrastructure
- Use wrapper types for domain concepts
Building Blocks
Entities
- Objects with identity that persists over time
- Defined by ID, not attributes
- Example: User, Order, Product
Value Objects
- Objects defined by their attributes
- Immutable
- Example: EmailAddress, Money, Address
Aggregates
- Cluster of entities and value objects
- One entity is the aggregate root
- External references only to root
- Enforces invariants
Domain Events
- Record of something that happened in the domain
- Immutable facts
- Enable event-driven architectures
Repositories
- Abstraction for accessing aggregates
- Provides collection-like interface
- Hides persistence details
Domain Services
- Operations that don’t belong to entities or value objects
- Stateless operations on domain objects
Anti-Patterns
Anemic Domain Model
- Domain objects are just data containers
- All logic in separate service layer
- Loses benefits of OOP and encapsulation
DDD and Persistence
- Domain model purity vs. current time
- Domain model purity vs. lazy loading
- Separation of domain logic from infrastructure concerns
Resources
Examples
Further Reading
- Domain-Driven Design in Practice
- Domain Driven Design - Jimmy Bogard
- Domain model purity and the current time
- Domain model purity and lazy loading