Arquitectura Limpia y Hexagonal
Nivel intermedio-avanzado — el principio de inversión de dependencias, visto desde Clean Architecture y desde Ports & Adapters.
El problema
El código típico tiene dependencias en todas direcciones: el controlador conoce la base de datos, el servicio conoce el framework HTTP, la lógica de negocio está mezclada con queries SQL. Cambiar de PostgreSQL a MongoDB, o de Express a Fastify, obliga a reescribir media aplicación.
Código acoplado es difícil de testear (necesitas base de datos real y Stripe para probar lógica de negocio), difícil de cambiar (cada modificación puede romper múltiples capas), y difícil de entender (la lógica está enterrada entre código de infraestructura). // un controlador que hace queries SQL directamente es la firma de este problema
Clean Architecture (Robert C. Martin)
Organiza el código en capas concéntricas donde las dependencias apuntan siempre hacia adentro, hacia el dominio.
| Capa | Contiene | NO conoce a |
|---|---|---|
| Entities | Objetos de dominio, reglas de negocio enterprise | Todo lo demás |
| Use Cases | Lógica de aplicación específica | Controllers, DB |
| Interface Adapters | Controllers, repos impl, presenters | Frameworks |
| Frameworks & Drivers | Express, PostgreSQL, React | — |
Regla crítica: las flechas de dependencia solo apuntan hacia adentro. El dominio no conoce nada de las capas externas.
Arquitectura Hexagonal (Alistair Cockburn)
Ve la aplicación como un hexágono con puertos (interfaces) y adaptadores (implementaciones concretas).
| Concepto | Descripción | Ejemplo |
|---|---|---|
| Puerto (Port) | Interfaz que define cómo el core se comunica con el exterior | OrderRepository interface |
| Adaptador (Adapter) | Implementación concreta de un puerto | PostgresOrderRepository |
| Puerto de entrada | Cómo el exterior llama al core | CreateOrderUseCase |
| Puerto de salida | Cómo el core llama al exterior | PaymentGateway |
El principio compartido: inversión de dependencias
OrderService (dominio) ──→ PostgresRepo (infra)
El dominio CONOCE y DEPENDE de PostgreSQL
✓ Dependencia invertida (clean):
OrderService ──→ <<interface>> OrderRepository ←── PostgresRepo
El dominio define la interfaz. La infra la implementa. El dominio no conoce PostgreSQL.
Cuándo aplicarlo
| Usa Clean/Hexagonal si... | Es overkill si... |
|---|---|
| Lógica de negocio compleja | CRUD simple sin reglas |
| Múltiples entry points (API, CLI, eventos) | Solo una API REST |
| Necesitas testear dominio sin infraestructura | Tests de integración son suficientes |
| Probable cambio de tecnologías | Stack estable a largo plazo |
| Sistema de larga vida (>3 años) | MVP o proyecto temporal |
Clean/Hexagonal reduce el coste de cambiar infraestructura más adelante, a cambio de más código (interfaces, adaptadores) desde el primer día. Para un CRUD simple con stack estable, esa inversión no se recupera nunca — es la misma lógica de la Lección 1.3: todo es un trade-off, y aquí el trade-off es velocidad inicial vs. flexibilidad futura.
Practica: refactoriza el espagueti
Tienes un servicio de pedidos con código acoplado: el controlador hace validación de negocio, queries SQL directas, y llama a Stripe sin abstracción, todo en la misma función.
Refactorízalo hacia Clean Architecture: extrae las Entities, define el Use Case, crea el puerto OrderRepository y el puerto PaymentGateway, e implementa los adaptadores concretos.