2022.06
Clean Architecture: conceptos
Una explicación clara y práctica sobre qué es Clean Architecture, cómo se organizan sus capas y por qué vale la pena entenderla.
Cuando uno escucha por primera vez sobre Clean Architecture, es fácil quedarse solo con el diagrama de círculos y una sensación vaga de “esto se ve importante”.
Pero la idea de fondo es bastante más simple:
organizar el software para que las reglas del negocio no dependan de frameworks, bases de datos, interfaces gráficas ni detalles externos.
Dicho de otra forma: que el corazón de la aplicación no quede amarrado a cosas que suelen cambiar con el tiempo.
La idea central
En una aplicación real, casi todo cambia:
- la base de datos,
- el framework,
- la forma en que expones la API,
- la librería de UI,
- incluso la manera en que recibes input.
Si toda la lógica importante del sistema depende directamente de eso, cada cambio externo empieza a arrastrar el resto del código.
Clean Architecture propone justo lo contrario:
hacer que el dominio y los casos de uso sean lo más independientes posible de los detalles externos.
Así el sistema se vuelve más fácil de entender, probar, mantener y evolucionar.
Capas de la Clean Architecture
Una manera común de entenderla es dividirla en estas capas:
- Domain layer: capa de dominio.
- Use cases layer: capa de aplicación.
- Adapter layer: capa adaptadora.
- Infrastructure layer: capa de infraestructura.
No todas las implementaciones se ven exactamente iguales, pero la idea general sí suele mantenerse.
Domain layer
La capa de dominio contiene las reglas más importantes del negocio.
Aquí viven las entidades, los objetos de valor y, en general, las definiciones que representan lo que el sistema es más allá de cómo se implementa.
Por ejemplo, si estás construyendo algo relacionado con órdenes, pagos o usuarios, esa lógica central debería vivir aquí, no escondida dentro de un controller, un ORM o una vista.
La capa de dominio debería poder existir incluso si mañana cambias de framework o de base de datos.
Use cases layer
La capa de casos de uso contiene la lógica de aplicación.
Aquí es donde defines qué hace el sistema en términos de acciones concretas:
- crear una orden,
- aprobar un pago,
- cancelar una reserva,
- actualizar inventario,
- etc.
El punto importante es que esta capa orquesta el comportamiento del sistema, pero sin depender directamente de detalles externos.
En otras palabras, los casos de uso deberían expresar la intención del negocio, no cómo habla tu framework con una base de datos o con una API.
Adapter layer
La capa adaptadora traduce entre el mundo externo y las reglas internas del sistema.
Aquí suelen vivir piezas como controllers, presenters y gateways.
Es una capa muy importante porque actúa como puente entre lo que entra o sale del sistema y lo que realmente entiende el dominio.
Controller
El controlador es responsable de responder a la entrada del usuario y realizar interacciones sobre los objetos del modelo de datos.
Recibe la entrada, la valida y luego ejecuta la operación de negocio que modifica el estado del modelo.
En muchas aplicaciones web, esta capa termina demasiado inflada porque se le mete lógica que no le corresponde. Idealmente, el controller debería ser delgado:
- recibe,
- transforma lo necesario,
- delega al caso de uso,
- devuelve una respuesta.
No debería convertirse en el lugar donde vive la lógica del negocio.
Presenters
El presentador actúa sobre el modelo y la vista.
Recupera datos desde los repositorios, es decir, desde el modelo, y los formatea para mostrarlos en la vista.
Su responsabilidad no es decidir reglas del negocio, sino traducir la información a una forma útil para quien la consume:
- una UI,
- una respuesta HTTP,
- un JSON,
- un DTO,
- etc.
Un presenter ayuda a que el caso de uso no tenga que preocuparse por detalles de presentación.
Gateways
Los gateways funcionan como adaptadores entre una fuente de datos, por ejemplo PostgreSQL, y un objeto de dominio en particular, por ejemplo una orden.
En lenguajes orientados a objetos, los gateways suelen ser clases que implementan una interfaz.
La entrada y salida puede ser cualquier dependencia externa a la aplicación, como:
- archivos,
- bases de datos,
- servicios externos,
- o llamadas HTTP a APIs.
La idea es que el resto del sistema no dependa directamente de esos detalles, sino de contratos más estables.
Infrastructure layer
La capa de infraestructura contiene justamente esos detalles externos:
- implementación concreta de repositorios,
- acceso a base de datos,
- clientes HTTP,
- colas,
- archivos,
- SDKs,
- servicios de terceros,
- etc.
Esta capa suele cambiar más seguido que el dominio o los casos de uso, así que conviene mantenerla bien aislada.
No porque sea “menos importante”, sino porque es más volátil.
¿Por qué vale la pena?
Porque ayuda a que el software no quede construido alrededor de herramientas, sino alrededor de reglas y decisiones de negocio.
Y eso normalmente trae varias ventajas:
- menos acoplamiento,
- mejor testabilidad,
- más claridad al leer el sistema,
- y menos dolor cuando cambian detalles de infraestructura.
Obviamente, no significa que haya que volver todo ultra abstracto ni sobrediseñar aplicaciones pequeñas.
Pero como criterio general, sí me parece bastante útil:
si una decisión importante del sistema depende demasiado de un framework o de un detalle externo, probablemente está en el lugar equivocado.
Cierre
Para mí, Clean Architecture no es tanto un diagrama bonito como una forma de recordar algo importante:
los detalles externos deberían servir al negocio, no gobernarlo.
Cuando eso se respeta, el sistema suele sentirse más estable, más entendible y más fácil de evolucionar.