Strategic design methodology focusing on modeling complex business domains through collaboration between domain experts and developers. Emphasizes creating a shared understanding of the business domain through ubiquitous language and bounded contexts.
Apply DDD principles when building complex business applications where domain complexity is the primary challenge.
Applies to: Complex business domains, enterprise applications, microservices architectures
Level: Strategic/Tactical - guides both high-level architecture and implementation patterns
Audience: Developers, Architects, Domain Experts, Product Teams
- Ubiquitous Language: Use domain-specific terminology consistently across code, documentation, and conversations
- Model-Driven Design: The domain model should drive the software design, not technical concerns
- Bounded Context: Define clear boundaries where a particular model applies and is valid
- RULE-001: All domain logic MUST be encapsulated within domain entities, value objects, or domain services
- RULE-002: Domain models MUST be free of infrastructure dependencies (repositories, databases, frameworks)
- RULE-003: Use ubiquitous language consistently in code - class names, methods, and variables MUST match domain terminology
- RULE-101: Aggregate roots SHOULD control access to entities within their boundary
- RULE-102: Domain events SHOULD be used to communicate between bounded contexts
- RULE-103: Repository interfaces SHOULD be defined in the domain layer, implemented in infrastructure
- RULE-201: Consider using specification pattern for complex business rules
- RULE-202: Implement factories for complex aggregate creation logic
- RULE-203: Use domain services for operations that don't naturally belong to a single entity
// Rich domain model with business logic
public class ProductIncident {
private IncidentReference reference;
private ProductCode productCode;
private IncidentStatus status;
public void resolve(ResolutionNotes notes) {
if (!canBeResolved()) {
throw new IncidentCannotBeResolvedException();
}
this.status = IncidentStatus.RESOLVED;
recordEvent(new IncidentResolvedEvent(reference, notes));
}
}
// Anemic domain model with getters/setters
public class ProductIncident {
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
// No business logic - violates DDD principles
}
When rules conflict:
- Domain model integrity takes precedence over technical convenience
- Ubiquitous language consistency overrides technical naming conventions
- Business rules in domain layer override performance optimizations
When facing edge cases:
- Consult domain experts to refine the model
- Consider if you've identified a new bounded context
- Evaluate if the complexity warrants DDD approach
Valid reasons for exceptions:
- Simple CRUD operations with minimal business logic (consider if DDD is needed)
- Performance-critical paths (document trade-offs clearly)
- Legacy integration constraints (temporary, with migration plan)
Process for exceptions:
- Document the exception and business justification
- Review with domain experts and technical leads
- Plan remediation if technical debt is introduced
- Automated checks: Domain layer must not depend on infrastructure packages
- Code review focus: Verify ubiquitous language usage and domain logic placement
- Testing requirements: Domain model must be testable without infrastructure dependencies
rules/clean-architecture.md
- Complementary architectural patternsrules/testing-strategy.md
- How to test domain models effectivelyrules/microservices-boundaries.md
- Bounded context implementation in distributed systems
- Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans
- Implementing Domain-Driven Design - Vaughn Vernon
- DDD Reference - Eric Evans' summary
Key Principles:
- Model the business domain, not technical concerns
- Use ubiquitous language consistently everywhere
- Define clear bounded contexts with explicit boundaries
Critical Rules:
- Must keep domain logic in domain layer only
- Must not reference infrastructure from domain
- Always use domain terminology in code
Quick Decision Guide: When in doubt: Ask "Does this serve the business domain or technical infrastructure?" Domain wins.