Clean Architecture
Organiza el código en capas concéntricas donde el dominio es el centro y nada de fuera lo toca.
Contexto
Formulada por Robert C. Martin (Uncle Bob) en 2012, como síntesis de Hexagonal, Onion y otras propuestas similares. Quieres aislar las reglas de negocio de detalles técnicos (framework, DB, UI) para poder cambiarlos sin reescribir el dominio.
Problema
Cuando el dominio depende de EF, ASP.NET o un broker concreto, los cambios técnicos rompen la lógica de negocio.
Solución
Capas concéntricas con la regla de dependencia: las dependencias apuntan hacia el centro, nunca hacia fuera.
┌──────────────────────────────────────┐
│ Frameworks & Drivers (Web, EF, MQ) │
│ ┌──────────────────────────────┐ │
│ │ Interface Adapters (DTOs, │ │
│ │ Controllers, Presenters) │ │
│ │ ┌──────────────────────┐ │ │
│ │ │ Use Cases (App) │ │ │
│ │ │ ┌──────────────┐ │ │ │
│ │ │ │ Entities │ │ │ │
│ │ │ └──────────────┘ │ │ │
│ │ └──────────────────────┘ │ │
│ └──────────────────────────────┘ │
└──────────────────────────────────────┘
#Las cuatro capas
- Entities: reglas de negocio de toda la empresa.
- Use Cases (interactors): reglas específicas de la aplicación; orquestan las entidades.
- Interface Adapters: controllers, presenters, gateways. Convierten datos entre el formato de los casos de uso y el de afuera.
- Frameworks & Drivers: web, base de datos, UI. Es el "pegamento" y los detalles.
#Qué la distingue de Hexagonal y Onion
- Es la más prescriptiva: nombra las capas, define el rol de los casos de uso como unidad central y dice cómo cruzan los datos las fronteras (estructuras simples, no entidades ni filas de la base).
- Hexagonal solo dice adentro/afuera; Onion pone el modelo de dominio como centro; Clean pone los casos de uso como protagonistas.
- En la práctica, las tres comparten la regla de dependencia. Si tu equipo ya aplica una de ellas bien, cambiar a otra casi nunca justifica el esfuerzo. Ver la comparativa.
#Reglas
- Dominio puro: sin
using Microsoft.EntityFrameworkCore, sin atributos web, sinDateTime.Now. - Casos de uso orquestan; no contienen reglas de dominio.
- Interfaces de salida (repositorios, services) viven en la capa Application, las implementan las capas externas (DI inversion).
#Estructura típica
CSHARP
src/
├── Domain/ ← Entidades, VOs, eventos, reglas. CERO dependencias.
├── Application/ ← Casos de uso, ports (IRepository, IClock). Depende solo de Domain.
├── Infrastructure/ ← EF, HTTP, MQ. Implementa los ports de Application.
└── Web/ ← ASP.NET. Compone el grafo DI.
// Application define el "puerto"
public interface IOrderRepository { Task<Order?> GetAsync(Guid id); }
// Infrastructure lo implementa
public class EfOrderRepository : IOrderRepository { /* ... */ }
// Web lo registra
services.AddScoped<IOrderRepository, EfOrderRepository>();Cuándo NO aplicarlo
- Microservicios pequeños o scripts: la ceremonia mata el ROI.
- Equipos sin disciplina para mantener las dependencias correctas.
Tradeoffs
| Pro | Contra |
|---|---|
| Dominio testeable sin infra | Más proyectos y boilerplate |
| Cambiar EF por Dapper sin tocar dominio | Mapeos extra entre capas |
| Encaja perfectamente con DDD | Curva de aprendizaje |
#architecture #clean #ddd