Review from Alexander
Part I: Strategic & Tactical Design
A detailed analysis of strategic and tactical design from the book by Vlad Khononov.
Learning Domain-Driven Design
Authors: Vlad Khononov
Publisher: O'Reilly Media, 2021
Length: 342 pages
Practical DDD from Vlad Khononov: strategic and tactical design, microservices, EDA and Data Mesh.
Original
TranslatedBook structure
The book consists of four parts, each of which covers an important aspect of DDD:
Part I: Strategic Design
Business subdomains, ubiquitous language, bounded contexts, team collaboration patterns.
Part II: Tactical Design
Implementation of business logic, architectural patterns, communication patterns.
Part III: Applying DDD in Practice
Design heuristics, evolution of solutions, Event Storming, brownfield projects.
Part IV: Relationships
Communication with microservices, event-driven architecture, data mesh.
Part I: Strategic Design
Business Subdomains
The author offers a classification of subdomains inherent in each company:
Core Subdomain
- Competitive advantage
- High difficulty
- Requires the best specialists
Supporting Subdomain
- Supports core
- Medium difficulty
- Can be outsourced
Generic Subdomain
- General solutions
- Finished Products
- Doesn't differentiate the business
Ubiquitous Language and Bounded Contexts
Ubiquitous Language — a single language used within the bounded context for the exchange of knowledge between domain experts and developers.
Business subdomains - this is something inherent to the company itself, they need to be found out. And here are the borders bounded contexts - on the conscience of the designer.
Team Collaboration Patterns
Cooperation Patterns:
- Partnership — close collaboration between teams
- Shared Kernel - common code between contexts
Customer-Supplier Patterns:
- Conformist — downstream accepts the upstream model
- Anti-Corruption Layer — protective layer of translation
- Open-Host Service - public API
To analyze the relationships between contexts, it is used Context Map.
Part II: Tactical Design
Business logic implementation options
Transaction Script
The simplest approach: procedural code organized by transactions.
Active Record
Objects that are aware of their storage and contain business logic.
Domain Model
Rich model with encapsulated logic, Aggregates, Entities, Value Objects.
Event-Sourced Domain Model
A state as a sequence of events, a complete history of changes.
Architectural patterns
Layered Architecture
Presentation → Business Logic → Data Access. Classic approach.
Ports & Adapters
Hexagonal / Clean Architecture. Dependency inversion.
CQRS
Separate read and write models for different requirements.
Patterns of communication between Bounded Contexts
Model Translation:
- Stateless Translation — stateless broadcast
- Stateful Translation — with data aggregation
Aggregate Integration:
- Outbox Pattern — reliable publication of events
- Saga — orchestration of distributed transactions
- Process Manager — complex coordination of processes
Part III: Putting DDD into Practice
Tactical Design Decision Tree
The author defines heuristics as “rule of thumb: not guaranteed to be perfect, yet sufficient for one’s immediate goals” and provides a decision tree:
1. Define the Subdomain type → Core / Supporting / Generic
2. Select your business logic implementation → Transaction Script / Active Record / Domain Model
3. Choose an architectural pattern → Layered / Ports & Adapters / CQRS
4. Determine your testing strategy → Unit / Integration / E2E
Vectors of Change
Changes in domains:
- Core → Supporting (commoditization)
- Supporting → Core (new benefit)
- Generic → Supporting (specialization)
Organizational changes:
- Partnership → Customer-Supplier
- Customer-Supplier → Separate Ways
- Team mergers and splits
Event Storming
Group modeling technique for gaining domain knowledge and forming a ubiquitous language:
Domain Events
Chronology
Triggers + Actors
Automation
Related book
Building Microservices
A practical guide to building microservices from Sam Newman - how to put DDD into practice.
Review from Alexander
Part II: DDD and Microservices
The relationship between Domain-Driven Design and microservice architecture.
Part IV: DDD and Microservices
What is a microservice?
Vlad is not talking about the size of the service itself, but about the size of it public interface, which should be “micro”.
Deep Services ✅
- Narrow public interface
- Complex internal logic
- Good encapsulation
- Controlled global difficulty
Shallow Services ❌
- Wide interface
- Simple implementation
- Poor encapsulation
- Rising Global Complexity
Granularity vs Complexity
The smaller the microservices → less local complexity of each, but more overall system complexity due to interactions.
The goal of good design is minimize overall complexity, not the size of individual services.
Heuristics for Microservice Boundaries
Bounded Context
Every microservice is a bounded context, but not vice versa!
Aggregates
The lower bound of the “depth” of a microservice.
Business Subdomains
The best heuristic! Correlate with business opportunities.
Review from Alexander
Part III: Event-Driven Architecture
Deep analysis of event-driven architecture in the context of DDD.
Event-Driven Architecture
EDA vs Event Sourcing
Event-Driven Architecture
- Architectural style
- Asynchronous communication
- Between system components
Event Sourcing
- Data storage pattern
- State as a chain of events
- Within one service
Message Types
Events vs Commands:
- Event - a fact that happened (past tense)
- Command - request for action (imperative)
Types of Events:
- Event Notification - notification of the fact
- Event-Carried State Transfer - with data
- Domain Event — business event
Types of Coupling in EDA
«Choosing the correct type of event message is what makes (decouples) or breaks (couples) a distributed system.»
Implementation Coupling
Dependency on implementation details
Functional Coupling
Dependency on business logic
Temporal Coupling
Runtime Dependency
Review from Alexander
Part IV: Data Mesh
Analysis of the Data Mesh concept and its connection with Domain-Driven Design.
Data Mesh
Analytical vs Transactional Data Model
Transactional (OLTP)
- High granularity
- Predictable queries
- Data Normalization
- Optimization for recording
Analytical (OLAP)
- Aggregated data
- Ad-hoc requests
- Star / Snowflake schema
- Reading optimization
DWH and Data Lake problems
- Centralised ownership → bottleneck
- Hard coupling via ETL
- One model for the entire organization
- Data swamp
- Loss of context
- Data quality issues
Four Data Mesh Principles
1. Domain Ownership
Domain teams own their insights.
2. Data as a Product
Data is a product with SLA, documentation, versioning.
3. Self-Serve Platform
Platform for self-service publication and consumption of data.
4. Federated Governance
Decentralized management with common standards.
Data Mesh combines well with DDD: bounded contexts become data products, a ubiquitous language defines the data schema.
Application at System Design Interview
When to use DDD:
- Defining service boundaries using bounded contexts
- Selecting an architecture based on subdomain type
- Integration design (ACL, Open-Host)
- Event Storming for the discovery phase
Key Concepts:
- Deep Services — narrow interface, rich logic
- Aggregates - lower boundary of a microservice
- Context Map — integration map
- EDA patterns - for loose coupling
