Domain-Driven Design (DDD) tactical patterns, introduced by Eric Evans in his 2003 "Blue Book," provide building blocks for modeling complex business domains in code. The core insight is that the model and the code must share the same language — the Ubiquitous Language — to prevent translation errors between developers and domain experts. Tactical patterns include Entities, Value Objects, Aggregates, Repositories, and Domain Services, each with precise responsibilities. DDD works best in bounded contexts with complex invariants; use simpler CRUD approaches for trivial domains.

Key Points

  • Entity: an object with a stable identity (ID) that persists over time and through state changes — e.g., Order, Customer.
  • Value Object: immutable, identity-less object defined entirely by its attributes — e.g., Money(100, USD), Address. Equality is structural.
  • Aggregate: a cluster of Entities and Value Objects with a single Aggregate Root that enforces consistency invariants across the cluster.
  • Only the Aggregate Root is accessible from outside — external objects hold references only to the Root, never to internal members.
  • Repository: abstracts aggregate persistence; exposes collection-like semantics (find, save, remove) and hides query/ORM details.
  • Domain Service: stateless operation that does not belong to any single Entity — e.g., TransferService.transfer(from, to, amount).
  • Domain Events: capture "something important happened" in the domain — OrderPlaced, PaymentFailed — enabling loose coupling between bounded contexts.
  • Anti-Corruption Layer (ACL): translates between your domain model and external systems, preventing external concepts from leaking into your core domain.

Real-World Example

Shopify models its Order aggregate root with strict invariants: line items, discounts, and taxes are internal members — only Order can modify them. Domain Events (OrderCreated, OrderFulfilled) drive downstream services like inventory and notifications via Kafka topics.