Arquitectura hexagonal en Java
Una guia rápida y practica de arquitectura hexagonal en Java
1. Introducción
Este es un simple tutorial para entender de manera práctica un tipo de arquitectura hexagonal
2. Que es la arquitectura hexagonal?
En principio nos adentraremos al concepto y las ventajas de este esquema.
Esta arquitectura propone un diseño de aplicación de acuerdo a una estructura circular en capas o anillos. De acuerdo a esta disposición, el core de la solución, se encuentra totalmente desacoplado del resto de plataformas externas que la integran como Base de datos, REST Services, SOA, LDAP o SMTP:
Esta separación la implementamos mediante puertos y adaptadores bien definidos, los cuales conformarán un anillo de segundo nivel con respecto al anillo central.
3. A Simple Implementation
Crearemos una solución muy sencilla siguiendo los principios de esta arquitectura.
3.1. The core
En primer lugar, definiremos nuestra aplicación como una API aislada y agnóstica a cualquier tipo de entorno o contexto, ya sea mobile, web o desktop.
El core estará compuesto por el dominio, utilidades, helpers y servicios. Para este ejemplo implementaremos una clase de dominio:
@Entity
public class Article {
private String title;
private int subject;
private StringBuilder text;
//getters and setters
}
Nuestro objetivo será adherir a nuestra aplicación, la capacidad de notificar nuestros artículos vía mail.
3.2. The ports
De acuerdo a esta perspectiva, nuestro core se situará en el centro del hexágono “rodeado” por puertos, que serán representados por interfaces. Las cuales, definirán los contratos que serán implementados por los Adaptadores. Siguiendo nuestro ejemplo de notificación:
public interface ArticleNotificationPort {
public void notificate(Article article);
}
3.3. The Adapters
Implementamos el adaptador con la notificación concreta. En este caso, utilizaremos a fines prácticos la API SimpleMail de Apache commons pero podría ser implementado con cualquier otra librería de mail o notificaciones.
@Service
public class ArticleNotificationAdapterImpl implements ArticlePublicationPort {
@Override
public void notificate(Article article) {
SimpleEmail email = new SimpleEmail();
email.setHostName(«localhost»);
email.setSmtpPort(25);
email.setAuthenticator(new DefaultAuthenticator(
«admin»,
«baeldung»));
email.setFrom(«server@mail.com»);
email.setSubject(«Sharing article with you » + article.getTitle());
email.setMsg(article.getContent());
email.send();
}
}
3.4. Usage
Y finalmente, retornando a la capa core (el anillo central), implementamos un servicio que utilizará nuestro adaptador:
public class ArticleNotificationService {
@Autowired
private ArticleNotificationPort articleNotification;
public void publish(Article article){
articleNotification.notificate(article);
}
}
Aprovechamos las bondades de Spring para desacoplarse de cualquier implementación de adaptador. Es decir, para seguir manteniendo nuestro core independiente a cualquier framework, librería, plataforma o protocolo definido en el anillo exterior.
4. Ports and Adapters Classifications
Los pares puertos-adaptadores se clasifican en primarios y secundarios. Donde los primarios son las implementaciones correspondientes a interacciones del usuarios mientras los secundarios refieren a interacciones con un servicio como un repositorio o storage.
De acuerdo a esta clasificacion, nuestro ejemplo ArticleNotificationPort / ArticleNotificationAdapterImpl estara catalogado como un puerto/servicio secundario.
Un fiel ejemplo de puerto/adaptador primario es la implementacion de un controlador para la GUI que atienda las solicitudes del usuario.
5. Beneficios
Esta arquitectura, nos permite mantener un diseño purista para el core de nuestra aplicación.
Este diseño nos brindara:
- Mantenibilidad: Las modificaciones en los adaptadores no afectarán la naturaleza de nuestro core.
- Escalabilidad: Se incorporan fácilmente nuevos canales especificando puertos e implementarlos con sus respectivos adaptadores.
- Testings: Se podrá probar de manera aislada nuestra API core sin estar sujeta al ambiente de base de datos, servidores HTTP, SMTP, etc.
6. Conclusión
En esta demostración, hemos implementado un sencillo ejemplo de la Arquitectura Hexagonal que nos permite verificar claramente cómo desacoplar el core de cualquier plataforma o framework externo.
Autor Ing. Rafael Benedettelli

