100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

Domain-Driven Design (DDD) Cheat Sheet

Domain-Driven Design (DDD) Cheat Sheet

Covers core DDD building blocks — entities, value objects, aggregates, repositories, domain events — plus bounded contexts and the ubiquitous language.

3 PagesIntermediateJan 15, 2026

Entities vs Value Objects

Entities have identity that persists through change; value objects are defined entirely by their attributes.

typescript
// Entity: identity matters, attributes can changeclass Order {  constructor(    readonly id: OrderId,       // identity — never changes    private items: OrderLine[],    private status: OrderStatus,  ) {}  addLine(line: OrderLine) { this.items.push(line); }}// Value Object: no identity, immutable, equality by valueclass Money {  constructor(readonly amount: number, readonly currency: string) {}  equals(other: Money): boolean {    return this.amount === other.amount && this.currency === other.currency;  }  add(other: Money): Money {    if (other.currency !== this.currency) throw new Error('currency mismatch');    return new Money(this.amount + other.amount, this.currency);  }}

Aggregates & Repositories

An aggregate is a consistency boundary with one root entity; repositories load/persist whole aggregates.

typescript
// Aggregate root: the only entry point for mutating the aggregateclass ShoppingCart {  private constructor(    readonly id: CartId,    private lines: CartLine[],  ) {}  static create(id: CartId): ShoppingCart {    return new ShoppingCart(id, []);  }  addItem(productId: ProductId, qty: number): void {    if (qty <= 0) throw new Error('quantity must be positive'); // invariant    this.lines.push(new CartLine(productId, qty));  }}interface CartRepository {  findById(id: CartId): Promise<ShoppingCart | null>;  save(cart: ShoppingCart): Promise<void>;}

Domain Events

Model significant business occurrences explicitly, decoupling side effects from the aggregate that raised them.

typescript
class OrderPlaced {  readonly occurredAt = new Date();  constructor(readonly orderId: OrderId, readonly total: Money) {}}class Order {  private events: DomainEvent[] = [];  place(): void {    this.status = OrderStatus.Placed;    this.events.push(new OrderPlaced(this.id, this.total));  }  pullEvents(): DomainEvent[] {    const events = this.events;    this.events = [];    return events;  }}// Application layer publishes events after the transaction commitsconst events = order.pullEvents();events.forEach(e => eventBus.publish(e));

DDD Glossary

Core vocabulary from Eric Evans' book and the community that followed.

  • Ubiquitous Language- shared vocabulary between developers and domain experts, used in code and conversation
  • Bounded Context- an explicit boundary within which a model and its language are consistent
  • Entity- object defined by continuity of identity, not attributes
  • Value Object- object defined by its attributes, immutable, no identity
  • Aggregate / Aggregate Root- cluster of objects treated as one consistency/transaction boundary
  • Repository- abstraction for loading/persisting whole aggregates, hides storage details
  • Domain Event- immutable record of something significant that happened in the domain
  • Context Mapping- explicit patterns (shared kernel, anti-corruption layer, etc.) for context relationships
Pro Tip

Keep aggregates small — one aggregate should protect exactly one true business invariant; reaching for a giant aggregate 'to be safe' is the most common DDD mistake and it kills both performance and concurrency.

Was this cheat sheet helpful?

Explore Topics

#DomainDrivenDesignDDD#DomainDrivenDesignDDDCheatSheet#Programming#Intermediate#EntitiesVsValueObjects#AggregatesRepositories#DomainEvents#DDDGlossary#OOP#CheatSheet#SkillVeris