Domain Driven Design — Cheat Sheet

Tag: ddd, architecture, microservices, aggregates, bounded-context, ubiquitous-language

Livello: advanced

TL;DR: Domain-Driven Design focuses on mapping complex business logic to software models through a Ubiquitous Language and bounded contexts. It separates domain logic from infrastructure, ensuring the software reflects the real-world business accurately.

Concetti chiave

Ubiquitous Language: A shared vocabulary between domain experts and developers to ensure accurate modeling without translation layers.

Bounded Context: A logical boundary within which a particular domain model is defined, valid, and strictly applicable.

Entities: Objects defined by a consistent thread of continuity and identity, not merely by their current data attributes.

Value Objects: Immutable objects that describe characteristics or attributes but have no unique identity (e.g., Money, DateRange).

Aggregates: Clusters of domain objects treated as a single transactional unit, encapsulating business rules and maintaining consistency.

Aggregate Root: The single entry-point entity for an aggregate, controlling all access to its internal objects to protect invariants.

Domain Events: Records of significant business occurrences that have happened in the past, used to decouple side effects.

Repositories: Abstractions that handle the retrieval and persistence of aggregates, mimicking an in-memory collection.

Anti-Corruption Layer (ACL): An isolation layer that translates between different subsystems to prevent pollution of the internal domain model.

Domande tipiche e risposte pronte

Q: What is the difference between an Entity and a Value Object?R: I always explain that an Entity has a distinct identity that persists over time, while a Value Object is immutable and defined entirely by its structural attributes.

Q: Why is the Aggregate Root so important?R: I use the Aggregate Root to enforce transactional consistency and business invariants. External objects can only hold references to the root, preventing the internal state from being bypassed or corrupted.

Q: How do Bounded Contexts relate to Microservices architecture?R: A Bounded Context is a logical boundary for a domain model. I typically map one Bounded Context to one microservice, which provides a natural architectural boundary and prevents tight coupling.

Insidie e errori comuni

Anemic Domain Model: Designing entities as mere data holders with public getters/setters, scattering the actual business logic across stateless services.

God Classes: Creating massive Aggregate Roots that handle too many responsibilities, leading to severe concurrency conflicts and unmaintainable code.

Ignoring the Ubiquitous Language: Translating business terms into generic technical jargon, causing friction and misunderstandings with domain experts.

Over-engineering: Applying complex DDD patterns to simple CRUD applications where a basic layered architecture would be far more efficient.

Snippet e comandiTypeScript

// Value Object: Immutable, no identity
class Money {
  constructor(public readonly amount: number, public readonly currency: string) {}

  equals(other: Money): boolean {
    return this.amount === other.amount && this.currency === other.currency;
  }
}

// Aggregate Root: Protects invariants and internal state
class Order {
  private status: 'Pending' | 'Confirmed' | 'Shipped';

  constructor(public readonly id: string, private total: Money) {
    this.status = 'Pending';
  }

  confirm(): void {
    if (this.status !== 'Pending') {
      throw new Error("Order must be in Pending state to be confirmed.");
    }
    this.status = 'Confirmed';
    // Domain Event dispatching would typically happen here
  }
}

Da ripassare

[ ] Event Sourcing integration with DDD aggregates.

[x] CQRS (Command Query Responsibility Segregation) to separate complex reads from domain writes.

Jarvis Interviews
Jarvis