Domain-Driven Design
Bounded contexts, aggregates, entities, value objects, ubiquitous language
Domain-Driven Design (DDD), formalized by Eric Evans in 2003, aligns software architecture with the business domain to manage complexity in large systems. The core building blocks are Bounded Contexts (explicit boundaries within which a domain model applies), Aggregates (consistency boundaries — a cluster of domain objects treated as a unit), and Entities vs. Value Objects (identity-based vs. value-based equality). Context Mapping defines relationships between bounded contexts: Shared Kernel, Customer-Supplier, Conformist, Anti-Corruption Layer. DDD is most valuable in complex domains with rich business rules — applying it to CRUD-heavy or technically-driven systems adds ceremony without benefit.
Key Points
- Ubiquitous Language: every concept in the domain model has a single precise name used consistently in code, docs, and conversations — eliminates translation overhead between engineers and domain experts.
- Bounded Context is the primary microservices decomposition strategy — one microservice per bounded context prevents models from bleeding into each other (e.g., "Order" means different things in Sales vs. Fulfillment vs. Finance).
- Aggregate Root is the single entry point for all mutations to an aggregate — nothing outside the aggregate may hold references to internal entities, only to the root (e.g., Order aggregate root; OrderLineItem is internal).
- Value Objects have no identity — two Money objects with the same currency and amount are interchangeable; make them immutable to prevent subtle bugs from shared mutable state.
- Domain Events communicate facts across bounded contexts asynchronously — "OrderPlaced" event triggers Inventory reservation and Email notification in separate bounded contexts without coupling.
- Anti-Corruption Layer (ACL) translates between bounded contexts with different models — shields your clean domain model from legacy system concepts or third-party API schemas.
- Context Map relationship types: Partnership (mutual dependency), Shared Kernel (shared subset of model), Customer-Supplier (downstream depends on upstream), Conformist (downstream adopts upstream model).
- DDD tactical patterns (Aggregate, Entity, Value Object, Repository, Domain Service, Domain Event) require less upfront investment than strategic patterns (Bounded Context, Context Map) — start with strategic.
Real-World Example
Uber's platform is organized around DDD bounded contexts: Rider, Driver, Trip, Payment, Maps, Surge Pricing — each with its own team, codebase, database, and ubiquitous language. The "Trip" context alone has sub-contexts for pre-trip, in-trip, and post-trip phases, demonstrating how DDD scales to handle the complexity of a global two-sided marketplace.