leanmind logo leanmind text logo

Blog

Código Sostenible

Cómo escribir código fácil de mantener mediante valores, principios y técnicas.

Mesa redonda, arquitectura hexagonal y organización de directorios

Por Cristian Suárez Vera y Yodra López Herrera

Tuvimos una sesión sobre cómo organizar los directorios en proyectos en los que trabajamos con arquitectura hexagonal. En esta publicación te dejamos nuestras notas y pensamientos después de la charla que mantuvimos. Aprovechamos, además, para compartir enlace al vídeo de la mesa redonda.

¿Qué es la arquitectura hexagonal? 🤔

La arquitectura hexagonal o de puertos y adaptadores es un patrón de diseño que define una serie de capas en nuestra aplicación. Estas capas son, desde la más exterior a la más interna:

Resumiendo mucho el significado de estas capas:

Las más externas son meros detalles de implementación.

Las más internas contienen lógica referente al negocio.

También nos indican que estas solo deben conocer detalles de las capas internas y nunca al revés. En el caso más extremo, un modelo no debe conocer nada de infraestructura; en cambio, la infraestructura sí que conoce el modelo que va a persistir. 💡 Es decir, al dominio no le importa cómo guardamos este modelo 🤷🏻‍♂️ si en MySQL o en Mongo, pero la infraestructura SÍ que tiene que conocer los campos del modelo para saber cómo guardarlos.

Diagrama de capas arquitectura hexagonal

Cuándo usar la arquitectura hexagonal

Queremos dejar claro que la arquitectura hexagonal no es la bala de plata que matará a los hombres lobo 🐺 , es decir, no vale para todos los problemas a los que nos enfrentemos en el día a día. Si tenemos delante una prueba de concepto en la cual basta con hacer un CRUD, no tiene sentido usar la arquitectura hexagonal. Estaríamos pecando de sobre-ingeniería 👀🎡.

Cada solución tiene su contexto y su momento, de igual manera, no tenemos por qué implementar esta arquitectura desde el minuto cero. Es mejor que el código nos vaya pidiendo cambios hasta llegar a la misma. Podemos ir desarrollando nuestra aplicación respetando patrones de diseño y, poco a poco, ir evolucionando nuestra arquitectura hasta que llegamos al punto en el que la podemos considerar hexagonal, si fuera la que mejor encaja. Es buena idea dejar que el proyecto evolucione por sí mismo. Si tenemos código de calidad, no será difícil ir cambiando la estructura con el paso del tiempo.

Muchas veces, la forma de estructurar nuestro proyecto, cómo gestionamos las dependencias entre módulos y cómo hacemos la separación de la lógica de negocio del resto de la aplicación, es algo que viene dado por el propio equipo y su forma de desarrollar. En ocasiones, lo adecuado es trabajar de la manera que mejor conocemos todos, la más cómoda, e ir solucionando los problemas que surjan (si los hubiera) aplicando patrones de diseño. Dejando que el proyecto evolucione por sí mismo. Lo importante en estos casos es hacer buen código de forma que sea fácil, a futuro, afrontar cambios de este tipo y tener una buena base de test para afrontar las modificaciones con seguridad.

Por otra parte, hay que tener en cuenta la tecnología que estamos usando, ya que no siempre es posible o intuitivo aplicar lo que ya conocemos de otros lenguajes. Por ejemplo, en ciertos casos, el propio framework o librería que usemos, nos guía hacia una forma de trabajo específica. En estas ocasiones, la estructura de directorios es algo que viene dado.

Clean Architecture

Y después de tanto hablar de evolucionar nuestro proyecto, tenemos que hacer una breve mención a Clean Architecture, el paradigma que envuelve a la arquitectura hexagonal y del que salen otras muy buenas propuestas. Estas son similares a la ya mencionada arquitectura de puertos y adaptadores, pero con algunos detalles cambiados. Uno de estos detalles es que no tenemos por qué obsesionarnos con estas tres o cuatro capas, no siempre tienen sentido o son necesarias. Lo que promueve Clean Architecture es a crear tantas capas como sean indispensables en tanto que respetemos los principios de ser testable e independiente de los frameworks, interfaces de usuario, bases de datos o cualquier agente externo.

Cómo organizar nuestros directorios

Llegados a este punto, nos dimos cuenta de que hay otras opciones. No siempre tenemos por qué usar la “clásica”

Además de esta opción, existen otras alternativas, como bien indica Yodra, con las cuales podemos hacer esta división, pero en un nivel inferior, creando estas tres capas en cada entidad del dominio.

Separación por entidades

Por ejemplo, si trabajamos con un carrito de la compra, tendríamos una carpeta cart y dentro de esta: model, application e infrastructure.

Estructurar de esta forma nuestro código tiene sentido, sobre todo cuando estamos desarrollando un servicio tipo API Rest, porque esta organización es muy similar a la que tendremos en las rutas expuestas del propio servicio.

Otro punto que consideramos una ventaja es que, a la hora de crear una nueva relación entre dos entidades, tenemos que pensar en un tercer nombre en el que podamos hacer una inyección de dependencias correctamente para evitar dependencias entre entidades.

Separación por acciones

Pero… ¿Y si vamos un paso más lejos y creamos estas mismas tres capas un nivel aún más bajo e instauramos la separación a nivel de acciones?

A simple vista, nos parece una idea mejorable. Rápidamente, vemos que tenemos que duplicar bastante código para hacerlo funcionar, porque si consideramos las tres acciones del carrito de la compra anterior, tendríamos que crear el mismo modelo en las tres. La aplicación, por tanto, sería más difícil de mantener.


Por último, dejar claro antes de acabar que todas estas son suposiciones teóricas.

¿Y tú? ¿Has usado alguna de estas formas para organizar tu proyecto?

Conclusiones

Es cierto que, en un principio, es complejo diferenciar correctamente las capas 🤯. Cuando te hablan por primera vez de aplicación, dominio, infraestructura, te quedas pensando: “¿Qué significa todo esto?, ¿dónde creo el fichero entonces?” Sobre todo en la capa de aplicación, esta capa es la más difícil de usar correctamente. Es tremendamente fácil que en ella acabe la lógica que debería estar en la parte de dominio, aún cuando la tecnología te resulte familiar.

Se nos quedan en el tintero varios temas a tratar. En concreto, Interaction domain driven design y cuánto nos casamos con una base de datos al usar su generador de ID/UUID ¿Te gustaría saber más de ellos en el futuro? ¡No te pierdas nuestros post!

Publicado el 05/02/2021 por
Cristian image

Cristian Suárez Vera

https://criskrus.com

Yodra image

Yodra López Herrera

https://yodralopez.dev

¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.

Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?

Impulsamos el crecimiento profesional de tu equipo de developers