System Design
Modelado del dominio
Explica cómo identificar entidades, value objects, agregados, reglas, eventos y límites para representar el dominio sin copiar tablas ni interfaces.
- Última actualización
- Actualizada
- Nivel
- Aplicación
System Design
Explica cómo identificar entidades, value objects, agregados, reglas, eventos y límites para representar el dominio sin copiar tablas ni interfaces.
El modelo de dominio no es una copia del esquema ni una colección de sustantivos. Es una representación de conceptos, decisiones, reglas y cambios que importan para resolver el problema.
Modelar el dominio consiste en descubrir qué conceptos tienen significado propio, qué información necesitan, qué comportamiento les corresponde y qué condiciones deben mantenerse siempre verdaderas.
lenguaje del negocio
→ conceptos
→ responsabilidades
→ reglas e invariantes
→ cambios de estado
→ colaboracionesEl resultado no tiene que ser un conjunto de clases. Puede expresarse mediante ejemplos, tablas de reglas, mapas conceptuales, estados, eventos y modelos orientados a objetos cuando estos ayuden.
Sin un modelo explícito, las reglas suelen dispersarse entre controladores, formularios, consultas y jobs. Dos partes del sistema terminan interpretando de manera distinta qué significa “stock disponible”, “pedido confirmado” o “crédito completado”.
El modelo de dominio concentra significado y permite detectar contradicciones antes de implementar.
Piensa el dominio como un conjunto de decisiones protegidas por conceptos con nombre.
Pedido
├─ conoce líneas, cliente y estado
├─ decide si puede confirmarse
├─ protege que tenga al menos una línea
├─ impide transiciones inválidas
└─ produce hechos como PedidoConfirmadoNo todo dato merece comportamiento propio, pero toda regla importante debe tener un lugar claro.
Parte de entrevistas, reglas, casos de uso y ejemplos reales. Busca palabras que cambian decisiones: reserva, entrega, devolución, sucursal, lote, vigencia.
Una entidad mantiene continuidad aunque cambien sus atributos. Dos pedidos con los mismos productos siguen siendo pedidos distintos porque poseen identidad propia.
Un value object se define por su contenido. Dos montos de 20 USD son equivalentes si moneda y valor coinciden. Suele ser inmutable y valida su propia consistencia.
Una invariante es una condición que debe preservarse después de cada operación válida.
- Una línea de pedido tiene cantidad mayor que cero.
- Un pedido confirmado contiene al menos una línea.
- El total es la suma de subtotales y cargos aplicables.
- Una entrega completada no vuelve a preparación.La operación debe vivir cerca de la información y reglas que necesita. order.confirm() expresa mejor la decisión que cambiar status libremente desde un controller.
Un evento de dominio representa algo relevante que ya ocurrió: OrderConfirmed, StockReserved, PaymentRejected.
Tiene identidad y ciclo de vida. Su igualdad no depende solo de los atributos.
Representa un valor con reglas: dinero, dirección, rango de fechas o cantidad. Reduce primitivas ambiguas.
Define lo que nunca debe quedar roto dentro del límite que la protege.
Es un límite de consistencia alrededor de una raíz. Las modificaciones externas ingresan por la raíz para preservar invariantes.
Un agregado no significa “grafo enorme de objetos”. Debe ser lo suficientemente pequeño para modificarse de manera coherente.
Contiene una decisión del negocio que no pertenece naturalmente a una sola entidad o value object. No debe convertirse en un contenedor genérico de toda la lógica.
Comunica un hecho relevante a otros participantes, pero no sustituye la validación ni garantiza por sí solo la entrega entre sistemas.
class Order {
private status: 'draft' | 'confirmed' | 'cancelled' = 'draft';
private readonly lines: OrderLine[] = [];
addLine(line: OrderLine) {
if (this.status !== 'draft') {
throw new Error('Only draft orders can be modified');
}
this.lines.push(line);
}
confirm() {
if (this.status !== 'draft') {
throw new Error('Only draft orders can be confirmed');
}
if (this.lines.length === 0) {
throw new Error('An order requires at least one line');
}
this.status = 'confirmed';
}
}El ejemplo muestra dos ideas: el estado no se modifica libremente y las operaciones preservan reglas. En producción faltaría identidad, dinero con precisión adecuada, eventos, persistencia y manejo de errores tipado.
Una reserva requiere decidir:
Un modelo pobre solo resta una columna. Un modelo útil distingue existencia física, cantidad reservada y cantidad vendible.
available = onHand - reserved - blockedLa fórmula es una regla del dominio; la estrategia de lock o transacción es una decisión técnica posterior.
El agregado intenta proteger invariantes que deben mantenerse juntas. No implica que toda operación de negocio que toca varios agregados deba convertirse en una transacción gigante.
Cuando una operación atraviesa límites, puede requerir coordinación, eventos, compensación o consistencia eventual.
Una tabla responde cómo persistir filas y relaciones. Una entidad responde qué representa algo y qué reglas gobiernan su vida.
No toda tabla necesita entidad de dominio: tablas de outbox, auditoría o proyecciones pueden existir por razones técnicas.
No toda entidad se almacena en una tabla independiente: un value object puede mapearse a columnas del propietario.
Decide si se genera al crear el objeto o al persistir. La elección afecta eventos y referencias.
La hora debe tratarse como dependencia controlable para poder probar vigencia y expiración.
Reevalúa el límite. Si la regla es realmente atómica, quizá pertenecen al mismo agregado; si no, define coordinación y estados intermedios.
Una autorización de banco o disponibilidad de proveedor no puede protegerse solo dentro del modelo local. Se necesita una política explícita ante timeout, rechazo o incertidumbre.
Entidades con getters y setters mientras toda decisión vive en servicios. La consecuencia es que cualquier parte puede romper reglas.
Un agregado enorme intenta controlar todo. Genera carga excesiva, conflictos y dificultad para evolucionar.
Las tablas existentes reflejan decisiones históricas, no necesariamente el lenguaje correcto actual.
Muchos sustantivos son atributos, roles o vistas, no conceptos con comportamiento propio.
Entidades, agregados y eventos son herramientas. Aplicarlos sin complejidad real añade capas y navegación.
Es especialmente valioso cuando existen reglas, estados, excepciones o lenguaje especializado. En CRUD muy simple puede bastar un modelo más ligero, pero incluso allí deben mantenerse claras validaciones e integridad.
isPaid, isCancelled e isDelivered pueden formar un modelo inválido?Modelo conceptual, lógico y físico explica cómo traducir este significado hacia estructuras persistentes sin mezclar niveles de decisión.