Command Palette

Search for a command to run...

ES·EN

Nivel 2 · 30 min

Domain-Driven Design

Domain-Driven Design (DDD) es un enfoque de diseño de software que pone el dominio de negocio al centro. Sus conceptos clave —bounded contexts, aggregates, ubiquitous language— guían cómo estructurar código complejo de manera sostenible.

Bounded Contexts y Ubiquitous Language

Un Bounded Context es un límite explícito dentro del cual un modelo de dominio es consistente. El mismo término puede tener significados diferentes en contextos distintos. El Ubiquitous Language es el vocabulario compartido entre desarrolladores y expertos del dominio dentro de un bounded context —el código usa los mismos términos que el negocio.

Aggregates y Entidades

Un Aggregate es un cluster de objetos de dominio que se tratan como una unidad. Tiene un Aggregate Root que es el único punto de acceso externo. Las invariantes de negocio se mantienen dentro del aggregate. Order es un aggregate root que contiene OrderItems —nadie puede acceder a OrderItems directamente, solo a través de Order.

Context Mapping

El Context Map describe las relaciones entre bounded contexts: Shared Kernel (modelo compartido), Customer-Supplier (upstream/downstream con contrato), Conformist (downstream adopta el modelo del upstream), Anti-Corruption Layer (traduce entre modelos diferentes). El ACL previene que el modelo externo ''contamine'' el propio.

Puntos clave

  • Los bounded contexts son los bloques naturales de microservicios —uno por bounded context.
  • Los aggregates definen los límites de consistencia y transaccionalidad —cada aggregate root tiene su propio repositorio.
  • La Anti-Corruption Layer protege tu modelo cuando integrás con sistemas externos que tienen modelos diferentes.

Code example

// Aggregate Root: Order controla OrderItems
public class Order {
  private OrderId id;
  private CustomerId customerId;
  private List<OrderItem> items = new ArrayList<'>();
  private OrderStatus status;

  public void addItem(Product product, int quantity) {
    if (status != OrderStatus.DRAFT) {
      throw new DomainException("Cannot add items to confirmed order");
    }
    items.add(new OrderItem(product.id(), product.price(), quantity));
  }

  public Money totalAmount() {
    return items.stream()
      .map(OrderItem::subtotal)
      .reduce(Money.ZERO, Money::add);
  }
}