Level 2 · 30 min
Domain-Driven Design
Domain-Driven Design (DDD) provides a vocabulary and set of patterns for aligning software architecture with business domain complexity. The bounded context is the central organizing concept — it defines where a specific domain model is valid.
Bounded Contexts and Ubiquitous Language
A bounded context is an explicit boundary within which a particular domain model applies. The same word ('order') can mean different things in different contexts — in the sales context, an order is a sales opportunity; in the fulfillment context, it is a shipping task. Mixing both meanings in one model creates confusion. Each bounded context has its own model, its own data schema, and its own service team. Ubiquitous language: a shared vocabulary between developers and domain experts, reflected consistently in code, tests, and conversations. When a domain expert says 'order', the code says Order. When the code says Invoice, the domain expert knows what that means. No translation layer — the language IS the model.
Aggregates, Entities, and Value Objects
An Entity has identity that persists through state changes — two entities with the same attributes are not the same if they have different IDs (two users named 'Alice' are different people). A Value Object has no identity — two value objects with the same attributes ARE the same (two '10 USD' money values are identical and interchangeable). Value objects are immutable: you don't change a price, you replace it. An Aggregate is a cluster of Entities and Value Objects with a single Aggregate Root (an Entity). The Aggregate Root is the only entry point — external code cannot hold references to internal entities directly. One Aggregate per transaction: all state changes within an aggregate are consistent (ACID within the aggregate). Changes that span aggregates are eventual: use domain events. Newman's concrete framing: 'From an implementation point of view, bounded contexts contain one or more aggregates. Some aggregates may be exposed outside of the bounded context, others may be hidden internally.' The aggregate boundary defines not just consistency but also the microservice deployment boundary — one aggregate per service is a useful starting heuristic. The ubiquitous language must survive the translation into code: when the language in code diverges from the domain experts' language, 'the engineers and the product owner were operating in completely different worlds.' — Sam Newman, Building Microservices (2nd ed.)
Context Mapping
Context Mapping defines how bounded contexts relate to each other. Key patterns: Shared Kernel: two teams share a subset of the domain model (high coupling, requires coordination). Customer-Supplier: upstream team (supplier) produces outputs that downstream team (customer) depends on. Conformist: downstream adopts upstream's model with no ability to influence it. Anti-Corruption Layer (ACL): translate between two models to prevent one from polluting the other — use when integrating with a legacy system or external API that has a different model. Open Host Service: define a published protocol (API) that other contexts can integrate with, decoupling their internal model from yours.
Code example
// Value Object (immutable, equality by value)\nclass Money {\n constructor(readonly amount: number, readonly currency: string) {}\n equals(other: Money): boolean {\n return this.amount === other.amount && this.currency === other.currency;\n }\n add(other: Money): Money { // Returns new instance (immutable)\n if (other.currency !== this.currency) throw new Error('Currency mismatch');\n return new Money(this.amount + other.amount, this.currency);\n }\n}\n\n// Aggregate Root controls access to child entities\nclass Order { // Aggregate Root\n private readonly items: OrderItem[] = []; // Child entities\n addItem(productId: string, quantity: number, price: Money): void {\n // Business rule: max 100 items per order\n if (this.items.length >= 100) throw new Error('Order item limit exceeded');\n this.items.push(new OrderItem(productId, quantity, price));\n }\n}