# Domain-Driven Design (DDD)

DDD is an approach to software design that emphasizes modeling the problem domain accurately and using that domain model as the foundation for architectural decisions.

---

## Two Levels of DDD

### Strategic Design (Big Picture)
How to divide the business domain and how parts interact.

| Pattern | Purpose |
|---|---|
| **Ubiquitous Language** | Shared language between developers and domain experts; reflected in code |
| **Bounded Context** | Explicit boundary where a model is consistent and valid |
| **Subdomain** | Business capability area (core, supporting, generic) |
| **Context Map** | Relationships between bounded contexts |

### Tactical Design (Implementation)
Patterns for concretely implementing domain models within each boundary.

| Pattern | Purpose |
|---|---|
| **Entity** | Object with identity that persists over time |
| **Value Object** | Immutable object defined by its attributes (no identity) |
| **Aggregate** | Cluster of entities/values with consistency boundary |
| **Repository** | Abstraction for persistence (collection-like interface) |
| **Domain Service** | Stateless behavior that doesn't belong to an entity |
| **Domain Event** | Something that happened in the domain |
| **Factory** | Encapsulates complex creation logic |
| **Specification** | Encapsulates business rules for querying |

---

## Ubiquitous Language

**The core practice**: Developers and domain experts use the *same terms* in conversation, code, tests, and documentation.

- If the business says "Policy", the class is `Policy`, not `PolicyEntity` or `PolicyDTO`
- Refactor language as understanding deepens
- Language lives in the **bounded context** — "Customer" means different things in Sales vs Support

---

## Bounded Contexts

A bounded context defines the **scope of a model's applicability**.

```
┌─────────────────────────────────────────────────────┐
│                   E-COMMERCE SYSTEM                 │
├──────────────────┬──────────────────┬───────────────┤
│   SALES          │   INVENTORY      │   SHIPPING    │
│   Context        │   Context        │   Context     │
├──────────────────┼──────────────────┼───────────────┤
│ Product:         │ Product:         │ Product:      │
│ - price          │ - SKU            │ - weight      │
│ - description    │ - quantity       │ - dimensions  │
│ - category       │ - warehouse_loc  │ - carrier     │
└──────────────────┴──────────────────┴───────────────┘
```

**Key rule**: A model is *only* valid within its bounded context. Don't share models across contexts — share *data* via contracts/anti-corruption layers.

---

## Context Mapping Patterns

| Pattern | Direction | When to Use |
|---|---|---|
| **Partnership** | ↔ | Two teams succeed/fail together; close coordination |
| **Shared Kernel** | ↔ | Small shared subset; explicit coordination |
| **Customer/Supplier** | → | Downstream (customer) drives upstream (supplier) priorities |
| **Conformist** | → | Downstream has no leverage; adopts upstream model |
| **Anticorruption Layer** | → | Protect domain from foreign/legacy model; translate |
| **Open Host Service** | → | Published protocol for many consumers |
| **Published Language** | ↔ | Well-documented shared language (OpenAPI, Protobuf) |
| **Separate Ways** | — | No integration needed; contexts truly independent |

---

## Subdomain Types

| Type | Description | Investment |
|---|---|---|
| **Core Domain** | What makes you money; your competitive advantage | Highest — best people, most rigor, DDD tactical patterns |
| **Supporting Subdomain** | Necessary but not differentiating | Medium — buy or build simply; don't over-engineer |
| **Generic Subdomain** | Commodity (auth, billing, email) | Lowest — buy/off-the-shelf; avoid custom code |

---

## Tactical Patterns Deep Dive

### Entity
- Has **identity** that persists across time and state changes
- Equality by identity, not attributes
- Example: `Order`, `User`, `Account`

### Value Object
- **No identity** — defined entirely by its attributes
- **Immutable** — replace instead of mutate
- Equality by value (structural equality)
- Example: `Money`, `Address`, `Email`, `DateRange`
- **Prefer value objects** — they're simpler, safer, more testable

### Aggregate
- **Consistency boundary** — a cluster of entities/values treated as a unit
- Has a **root entity** (aggregate root) — only it can be referenced externally
- All external access goes through the root
- Invariants enforced *within* the aggregate boundary
- One transaction per aggregate (ideally)

```
Order (Aggregate Root)
├── OrderLine[] (Entities)
├── ShippingAddress (Value Object)
└── BillingAddress (Value Object)

Invariant: Order.total = sum(line.price * line.quantity)
```

### Repository
- **Collection-like interface** for aggregate persistence
- `add(aggregate)`, `get(id)`, `remove(aggregate)`
- **Interface in domain**, implementation in infrastructure
- One repository per aggregate root (not per entity)

### Domain Service
- Stateless operation that doesn't naturally belong to an entity/value
- Named from ubiquitous language: `TransferService`, `PricingEngine`
- Not the same as application service (which orchestrates)

### Domain Event
- Something that happened that domain experts care about
- Immutable, past tense: `OrderPlaced`, `InventoryReserved`
- Published by aggregate; consumed by other aggregates/sagas
- Enables eventual consistency across aggregates/contexts

---

## DDD + Hexagonal Architecture

They're complementary:

```
┌─────────────────────────────────────┐
│         HEXAGONAL LAYERS            │
├─────────────────────────────────────┤
│  Primary Adapters (Driving)         │  ← Controllers, CLI, Consumers
├─────────────────────────────────────┤
│  Application Services               │  ← Use cases, orchestrate aggregates
├─────────────────────────────────────┤
│  DOMAIN LAYER (Bounded Context)     │
│  ├─ Entities                        │
│  ├─ Value Objects                   │
│  ├─ Aggregates                      │
│  ├─ Domain Services                 │
│  ├─ Domain Events                   │
│  ├─ Repository Interfaces (Ports)   │
│  └─ Domain Event Publishers (Ports) │
├─────────────────────────────────────┤
│  Secondary Adapters (Driven)        │  ← Repositories, Event Publishers
├─────────────────────────────────────┤
│  Infrastructure                     │  ← DB, Message Broker, External APIs
└─────────────────────────────────────┘
```

**Why they fit**: DDD wants domain isolated; Hexagonal provides the mechanism (ports/adapters).

---

## Anti-Patterns to Avoid

| Anti-Pattern | Description |
|---|---|
| **Anemic Domain Model** | Entities are just data bags; logic lives in services |
| **God Aggregate** | One aggregate spans too much; becomes bottleneck |
| **Chatty Aggregates** | Aggregates calling each other directly |
| **Leaky Contexts** | Sharing domain models across bounded contexts |
| **Infrastructure Leakage** | DB concerns (IDs, annotations) in domain model |
| **DDD Lite** | Using tactical patterns without strategic design (ubiquitous language, bounded contexts) |

---

## When to Use DDD

| Use DDD When | Don't Use DDD When |
|---|---|
| Complex business logic/rules | Simple CRUD applications |
| Domain evolves frequently | Short-lived prototypes |
| Multiple domain experts involved | Technical complexity only (no domain complexity) |
| Long-term system (5+ years) | Team unfamiliar with DDD (steep learning curve) |
| Need for clear boundaries | |

---

## Related Notes

- [[Architecture/Architectural-Styles]] — Hexagonal/Clean as DDD enablers
- [[Architecture/CQRS-Event-Sourcing]] — Advanced patterns for aggregates
- [[Architecture/Design-Principles]] — Principles underlying DDD
- [[Patterns/Design-Patterns]] — Repository, Factory, Specification as patterns
- [[Testing/Test-Driven-Development]] — TDD with aggregates

---

*Sources: Domain-Driven Design (Eric Evans), Advanced Beginner DDD Guide, AWS Prescriptive Guidance, Vaughn Vernon (Implementing DDD), Martin Fowler, Software Engineering: A Modern Approach*