MÓDULO 3 · ARQUITECTURA DE SISTEMAS CONVERSACIONALES · LECCIÓN 4.1 · 45 MIN

Arquitectura Limpia y Hexagonal

Nivel intermedio-avanzado — el principio de inversión de dependencias, visto desde Clean Architecture y desde Ports & Adapters.

Idea central El código de alto nivel (dominio) no debe depender de código de bajo nivel (infraestructura). Ambos deben depender de abstracciones — es el mismo principio detrás de Clean Architecture y de la Arquitectura Hexagonal, dibujado de dos formas distintas.

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.

CapaContieneNO conoce a
EntitiesObjetos de dominio, reglas de negocio enterpriseTodo lo demás
Use CasesLógica de aplicación específicaControllers, DB
Interface AdaptersControllers, repos impl, presentersFrameworks
Frameworks & DriversExpress, 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).

ConceptoDescripciónEjemplo
Puerto (Port)Interfaz que define cómo el core se comunica con el exteriorOrderRepository interface
Adaptador (Adapter)Implementación concreta de un puertoPostgresOrderRepository
Puerto de entradaCómo el exterior llama al coreCreateOrderUseCase
Puerto de salidaCómo el core llama al exteriorPaymentGateway

El principio compartido: inversión de dependencias

✗ Dependencia incorrecta (tradicional):
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 complejaCRUD simple sin reglas
Múltiples entry points (API, CLI, eventos)Solo una API REST
Necesitas testear dominio sin infraestructuraTests de integración son suficientes
Probable cambio de tecnologíasStack estable a largo plazo
Sistema de larga vida (>3 años)MVP o proyecto temporal
La complejidad se paga por adelantado

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.