Back to results for “Architecture & Design Patterns”
Node.js › Architecture & Design Patterns

What is Domain-Driven Design (DDD), and how do its concepts of entities, value objects, and aggregates apply to a Node.js codebase?

Advanced

Answer

Domain-Driven Design structures code around the business domain itself rather than technical layers -- an entity is an object with a distinct identity that persists over time (a User with a stable ID), a value object is defined entirely by its attributes with no identity of its own (an Address or a Money amount, where two instances with identical values are interchangeable), and an aggregate is a cluster of entities and value objects treated as a single consistency boundary, with one designated 'aggregate root' controlling all access and enforcing invariants for the whole cluster.
class Money { // value object: equality is by value, and it's immutable
  constructor(amount, currency) { this.amount = amount; this.currency = currency; Object.freeze(this); }
  equals(other) { return this.amount === other.amount && this.currency === other.currency; }
}

class Order { // entity: has identity, and acts as the aggregate root
  constructor(id) { this.id = id; this.items = []; this.total = new Money(0, 'USD'); }
  addItem(item) { this.items.push(item); this.total = this.recalculateTotal(); }
}
Real-world example An e-commerce backend models Order as an aggregate root that owns its OrderLineItems, ensuring that any modification (like adding an item) always goes through the Order object itself so that invariants like 'total must equal the sum of line items' can never be violated by code modifying a line item directly.

Common follow-ups: How much of full DDD (bounded contexts, ubiquitous language) is realistic to adopt incrementally versus needing a full rewrite?;What's the practical difference between a value object and a plain object literal in JavaScript, given JS doesn't enforce immutability by default?