Domain Driven Design
¿Por qué se llama "Domain-Driven Design"?
La clave está en entender qué es el DOMINIO y por qué el diseño debe estar "DIRIGIDO" por él.
¿Qué es el DOMINIO?
El dominio es el área de conocimiento o actividad del negocio que estás intentando resolver con software. Es la realidad del mundo real, las reglas del negocio, los procesos, el lenguaje que usan los expertos del negocio.
Ejemplos de Dominios:
🏦 Banca: Cuentas, transacciones, tipos de interés, regulaciones
🏥 Hospital: Pacientes, diagnósticos, tratamientos, citas médicas
🛒 E-commerce: Productos, carritos, órdenes, inventario
📚 Biblioteca: Libros, préstamos, multas, reservas
¿Qué significa "Driven" (Dirigido)?
Significa que el DOMINIO es el que manda, no la tecnología. El software debe modelar la realidad del negocio, no al revés.
❌ Lo que NO es DDD (enfoque técnico):
// Pensando en la base de datos primero
public class OrderTable
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
public decimal TotalAmount { get; set; }
public DateTime CreateDate { get; set; }
public string Status { get; set; }
}
// El modelo es solo un contenedor de datos
// No refleja las reglas del negocio✅ Lo que SÍ es DDD (enfoque en dominio):
// Modelando cómo funciona realmente una orden en el negocio
public class Order
{
public OrderId Id { get; private set; }
public CustomerId CustomerId { get; private set; }
public Money Total { get; private set; }
public OrderStatus Status { get; private set; }
private List<OrderLine> _lines = new();
// Las reglas del NEGOCIO están en el modelo
public void AddProduct(Product product, int quantity)
{
// REGLA: No puedo agregar productos a una orden ya enviada
if (Status == OrderStatus.Shipped)
throw new InvalidOperationException(
"No se pueden agregar productos a una orden enviada"
);
// REGLA: Cantidad debe ser positiva
if (quantity <= 0)
throw new ArgumentException("La cantidad debe ser mayor a 0");
_lines.Add(new OrderLine(product, quantity));
RecalculateTotal();
}
public void Ship()
{
// REGLA: Solo puedo enviar órdenes confirmadas
if (Status != OrderStatus.Confirmed)
throw new InvalidOperationException(
"Solo se pueden enviar órdenes confirmadas"
);
// REGLA: Debe tener al menos un producto
if (!_lines.Any())
throw new InvalidOperationException(
"No se puede enviar una orden vacía"
);
Status = OrderStatus.Shipped;
ShippedAt = DateTime.UtcNow;
}
}
```
---
## Ejemplo REAL: Sistema Bancario
Imagina que trabajas para un banco y te piden crear un sistema de **transferencias entre cuentas**.
### 🎯 Conversación con el Experto del Negocio
```
Tú: ¿Cómo funciona una transferencia?
Experto Bancario:
- El cliente debe tener fondos suficientes
- Si es una transferencia internacional, hay un límite de $10,000 por día
- Las transferencias después de las 6pm se procesan al día siguiente
- Si es a otra moneda, aplicamos el tipo de cambio del día
- Cobramos una comisión de $5 para transferencias internacionales
- El cliente debe confirmar la transferencia con su token de seguridad