Arquitectura Hexagonal: Puertos y Adaptadores en Desarrollo de Software

Clase 6 de 24Curso de Arquitecturas Limpias para Desarrollo de Software

Contenido del curso

Resumen

Diseñar software que resista el paso del tiempo y los cambios tecnológicos es uno de los retos más importantes en ingeniería. La arquitectura hexagonal ofrece una forma clara de lograrlo, separando el corazón de la aplicación de todo lo que la rodea mediante dos elementos clave: los puertos y los adaptadores. A continuación, se explican los fundamentos de este patrón y cómo aplicarlo en proyectos reales.

¿Qué es la arquitectura hexagonal y por qué importa?

La arquitectura hexagonal fue descrita por Alistair Cockburn en 2005 [09:36] y también se conoce como ports and adapters. Su idea central es colocar el dominio —al que Cockburn llama aplicación— en el centro de un hexágono, completamente aislado de los detalles externos como bases de datos, interfaces gráficas o servicios HTTP.

Esta forma geométrica no es casual: Cockburn eligió el hexágono porque ofrece espacio visual suficiente para representar varios puertos y adaptadores alrededor de la aplicación [10:20]. Si tu sistema necesita más o menos conexiones, puedes ajustar la representación sin que el patrón pierda validez.

¿Qué papel cumplen los puertos?

Los puertos funcionan como puentes hacia la aplicación [01:05]. Son contratos o interfaces que definen cómo el mundo exterior puede comunicarse con el dominio. En un ejemplo de un sistema de gestión de clientes (CRM), se podrían identificar al menos dos puertos:

  • API de clientes: permite las operaciones relacionadas con la gestión de clientes.
  • API de persistencia: define cómo se almacenan y recuperan los datos.

Lo fundamental es que los puertos pertenecen a la aplicación, no a los elementos externos.

¿Qué son los adaptadores y cómo se conectan?

Los adaptadores se ubican sobre los puertos y se encargan de convertir lo externo hacia lo que la aplicación entiende [02:22]. Cada adaptador traduce un lenguaje específico al contrato que define el puerto.

Ejemplos concretos de adaptadores:

  • Una interfaz gráfica que transforma eventos de botones, campos de texto y navegación del usuario en llamadas al API de clientes [02:48].
  • Una clase específica para MySQL que traduce las operaciones de persistencia a consultas SQL [03:20].
  • Un API REST que maneja temas de HTTP, conversión de datos en formato JSON o XML, y los adapta al puerto de clientes [04:25].
  • Objetos mock que facilitan las pruebas de integración sin depender de una base de datos real [05:15].

Aquí aparece con fuerza el principio de abierto-cerrado [04:05]: la aplicación permanece cerrada a modificaciones, pero abierta a extensiones. Para agregar una nueva forma de interacción, basta con crear un nuevo adaptador sin tocar el dominio.

¿Cómo funciona la regla de la dependencia en este contexto?

La regla de la dependencia establece que los elementos externos conocen lo que hay hacia adentro, pero nunca al revés [05:45]. La aplicación jamás debe saber qué adaptadores se están usando a su alrededor; debe ser completamente transparente y agnóstica respecto a la tecnología externa.

Esto garantiza que cambiar MySQL por PostgreSQL, o reemplazar una interfaz gráfica por un API REST, no obligue a modificar ni una línea del dominio.

¿Qué diferencia hay entre actores primarios y secundarios?

Dentro de la arquitectura hexagonal se distinguen dos tipos de actores según su rol en las interacciones [06:18]:

  • Actores primarios: son adaptadores que inician interacciones con el sistema. Por ejemplo, una interfaz gráfica donde un usuario envía un formulario. Esa acción pasa por el puerto y llega a la aplicación [06:40].
  • Actores secundarios: son adaptadores que reciben notificaciones de la aplicación. No inician interacciones, sino que participan en un flujo ya iniciado. Un ejemplo claro es la base de datos: cuando la aplicación necesita guardar información, solicita esa operación a través del puerto correspondiente [07:30].

El flujo típico sería: un actor primario (la interfaz) dispara una acción → esta llega a la aplicación a través del puerto → la aplicación procesa la lógica → y notifica a un actor secundario (la base de datos) para completar la operación.

Si estás trabajando en un proyecto ahora mismo, piensa cuáles serían los puertos y adaptadores de tu aplicación. Compartir ese análisis en los comentarios es un excelente ejercicio para empezar a identificar qué pertenece al dominio y qué debe vivir en una capa externa.