Learning Domain Driven Design
Strategic Design
- Ubiquitous language: Establish a shared language between technical and domain experts to eliminate translation
- Domain knowledge extraction: Extract domain knowledge from domain experts through collaborative modeling sessions
- Bounded context identification: Identify bounded contexts to create clear boundaries for models and subsystems
- Context mapping: Document relationships between bounded contexts using context maps
- Integration patterns: Choose appropriate integration patterns between contexts based on team relationships
- Domain expert collaboration: Collaborate closely with domain experts throughout the design process
- Core domain focus: Identify and focus resources on your core domain, where competitive advantage lies
- Subdomain classification: Classify subdomains as core, supporting, or generic to prioritize investment
- Strategy alignment: Align technical decisions with business strategy and organizational structure
- Conway’s law consideration: Consider Conway’s Law when designing boundaries - system architecture reflects team structure
Tactical Design
- Entity modeling: Model entities with identity that persists across state changes
- Value object usage: Use value objects for attributes that have no identity of their own
- Aggregate definition: Define aggregates as consistency boundaries with a single entry point
- Aggregate root access: Access aggregate members only through the aggregate root
- Transaction boundary: Make each aggregate a transaction boundary for data consistency
- Aggregate size limitation: Keep aggregates small to minimize contention and performance issues
- Domain event implementation: Implement domain events to communicate between aggregates
- Service placement: Place services in the appropriate layer - domain, application, or infrastructure
- Repository abstraction: Use repositories to abstract data access for aggregates
- Factory implementation: Implement factories for complex object creation
Domain Modeling
- Knowledge crunching: Engage in knowledge crunching to distill complex domain concepts
- Model refinement: Continuously refine models based on new domain insights
- Analysis patterns: Apply analysis patterns to common modeling problems
- Model truth: Ensure the model truthfully represents the domain, not technical convenience
- Behavior encapsulation: Encapsulate behavior with data in cohesive objects
- Rule extraction: Extract domain rules explicitly from implicit knowledge
- Language consistency: Maintain consistency in language throughout the model
- Model documentation: Document models using diagrams and examples that domain experts can validate
- Domain storytelling: Use domain storytelling to understand complex workflows
- Example scenarios: Model key examples and edge cases to validate understanding
Bounded Contexts
- Context boundary establishment: Establish clear boundaries for each bounded context
- Public interface definition: Define clean public interfaces between bounded contexts
- Shared kernel management: Manage shared kernels carefully when contexts must share code
- Customer/supplier relationship: Establish customer/supplier relationships between upstream and downstream teams
- Anti-corruption layer implementation: Implement anti-corruption layers to protect models from legacy or external systems
- Open host service creation: Create open host services for contexts that must integrate with many clients
- Published language usage: Use published languages for standardized communication between contexts
- Conformist approach: Take a conformist approach when you must adapt to an external model
- Separate ways decision: Choose separate ways when integration costs exceed benefits
- Partnership relationship: Form partnerships between teams with aligned goals
Domain Events
- Event definition: Define domain events as significant occurrences in the domain
- Event sourcing consideration: Consider event sourcing for domains where history and audit are important
- Event storming facilitation: Facilitate event storming workshops to discover domain events
- Temporal modeling: Model temporal aspects of the domain through events
- Event ownership: Clearly define event ownership and publishing responsibilities
- Event schema management: Manage event schemas and versioning carefully
- Causality tracking: Track causality between events when order matters
- Event enrichment: Enrich events with context needed by consumers
- Event naming: Name events in past tense to indicate they’ve already happened
- Event notification vs. state transfer: Choose between event notification and state transfer based on coupling needs
Architectural Patterns
- Layered architecture implementation: Implement layered architecture to separate concerns
- Hexagonal architecture consideration: Consider hexagonal architecture to isolate domain from external systems
- CQRS implementation: Implement Command Query Responsibility Segregation when appropriate
- Event sourcing application: Apply event sourcing to capture all domain state changes as events
- Microservice boundary alignment: Align microservice boundaries with bounded contexts
- Modular monolith design: Design modular monoliths with clear boundaries between contexts
- Infrastructure service separation: Separate infrastructure services from domain services
- Query optimization: Optimize queries independently from command processing
- Read model denormalization: Denormalize read models for query performance
- Eventual consistency management: Manage eventual consistency with appropriate business rules
Domain-Driven Design in Practice
- Domain expert engagement: Engage domain experts continuously, not just at project start
- Model iteration: Iterate on models as domain understanding deepens
- Legacy system integration: Integrate with legacy systems through anti-corruption layers
- Brownfield adoption: Adopt DDD incrementally in brownfield projects
- Team structure alignment: Align team structure with bounded contexts where possible
- Technical debt management: Manage technical debt in the model as domain understanding evolves
- Process modeling: Model business processes explicitly, not just data
- Testing strategy: Develop a testing strategy that validates domain rules
- Documentation approach: Document the model for both technical and domain audiences
- Knowledge sharing: Share domain knowledge across the organization
Domain-Driven Design and Microservices
- Service boundary definition: Define service boundaries based on business capabilities
- Service autonomy: Design services to be autonomous with minimal dependencies
- Data ownership: Establish clear data ownership per service
- Distributed transaction handling: Handle distributed transactions through eventual consistency and sagas
- Service communication: Choose appropriate communication patterns between services
- API design: Design APIs to reflect domain concepts
- Service deployment: Deploy services independently to maximize team autonomy
- Service discovery: Implement service discovery mechanisms
- Resilience pattern application: Apply resilience patterns to handle failures
- Monitoring implementation: Implement monitoring to understand distributed system behavior
Strategic Design Heuristics
- Business value orientation: Orient design decisions around business value
- Problem space exploration: Explore the problem space before rushing to solutions
- Big picture focus: Focus on the big picture before diving into details
- Trade-off assessment: Assess trade-offs explicitly, especially between consistency and availability
- Organizational alignment: Align with organizational structure and constraints
- Iterative refinement: Refine understanding and models iteratively
- Technical risk management: Manage technical risk through clear boundaries and interfaces
- Knowledge investment: Invest in domain knowledge as much as technical knowledge
- Continuous learning: Embrace continuous learning as the domain evolves
- Communication emphasis: Emphasize communication over documentation
Key Takeaways
- Domain expertise: Invest in developing deep domain expertise and close collaboration with domain experts
- Bounded contexts: Establish clear bounded contexts with well-defined boundaries and relationships
- Ubiquitous language: Develop a ubiquitous language shared by technical and domain experts
- Model integrity: Maintain model integrity within bounded contexts through aggregates and consistent rules
- Context mapping: Document relationships between bounded contexts with context maps and integration patterns
- Strategic design: Focus on strategic design before tactical patterns to align with business value
- Core domain investment: Identify and invest heavily in your core domain where competitive advantage lies
- Continuous refinement: Continuously refine models as domain understanding deepens
- Communication patterns: Choose appropriate communication patterns between bounded contexts
- Team alignment: Align team structures with bounded contexts for optimal organizational design