Ni Nueva Ni Arquitectura Ni Hexagonal.Feb 20th, 2016

Ni Nueva Ni Arquitectura Ni Hexagonal

En los últimos tiempos parece haberse popularizado la idea de que las soluciones de software deben desarrollarse de acuerdo a un nuevo y revolucionario modelo arquitectónico. Se dice que este modelo no solamente confiere a estas soluciones unas propiedades características muy deseables sino que además ayuda enormemente en los procesos de construcción y desarrollo. En función de autores, comunidades y estilos, este modelo ha recibido diversos nombres a cada cual más rimbombante y pretencioso que el anterior. Arquitecturas de cebolla [1], arquitecturas limpias [2] o – para mi la más hilarante y estridente de todas – las arquitecturas hexagonales [3].

Es fácil hacerse una idea general de la propuesta arquitectónica que estos modelos hacen en relación a los procesos de desarrollo de soluciones de software. Basta con rascar un poco en la blogosfera actual o visitar los recientes eventos de IT para encontrarse con una pléyade de artículos y charlas introductorias que nos invitan a conocer esta nueva revolución en el mundo del diseño de software. No obstante, antes de pasar a comentar el dudoso valor añadido que aporta este tipo de contribuciones a la comunidad, describiremos de una manera objetiva la propuesta que se hace desde estos modelos. Aunque existen someras diferencias entre ellos, todos resultan francamente similares. Por tanto, nos centraremos en describir aquí el modelo que está cogiendo más tracción y que paradójicamente es el de las arquitecturas hexagonales.

Una arquitectura hexagonal conceptualiza la construcción de soluciones de software en base a la identificación de una colección de puertos y el desarrollo de una serie de adaptadores que se conectan a dichos puertos. Esta idea permiten implementar el modelo de negocio del aplicativo que se desea construir de una manera aislada de cualquier tipo de dependencia exterior de manera que los puertos se corresponden con puntos de entrada y salida a un núcleo funcional que puede ser atacado por distinto tipos de clientes o sistemas.

Ejemplo de una arquitectura hexagonal para un problema de ejemplo

Figura 1. Ejemplo de una arquitectura hexagonal para un problema de ejemplo.

Por ejemplo, si tenemos en cuenta el modelo arquitectónico hexagonal que se presenta en la figura 1, observamos que el funcional de negocio desarrollado de manera nuclear, en efecto, se encuentra completamente aislado de cualquier tipo de dependencia y que éste puede ser atacado por distintos tipos de sistemas desde diferentes flancos. En el ejemplo, con responsabilidades de front existe un adaptador para la web, otro para facilitar la integración con servicios en REST y uno último para realizar cómodamente la depuración basada en pruebas unitarias y TDD. Asimismo, desde el back, el soporte a la persistencia – o como algunos gustan en decir ahora, los sistemas de registro - están desacoplados de manera que puede utilizarse indistinta y simultáneamente una solución relacional o no SQL en sus diferentes sabores al mas puro estilo políglota como está últimamente en boga [4]. Otros puntos de desacoplamiento que aparecen en la figura de ejemplo tienen que ver con cuestiones de autenticación, monitorización e incluso virtualización asumiendo que tales capacidades fueran requerimientos demandados por el problema.

En sentido estricto, esta propuesta no es susceptible de critica alguna. Jamás señalaré a nadie que defienda las bondades del desacoplamiento en relación a la construcción de software. Los productos obtenidos de esta manera resultan más reutilizables, más modulares y más mantenible que otras aproximaciones. Si este modelo se considera como un mero marco conceptual que ayuda a adquirir buenas prácticas en procesos de diseño y desarrollo de la solución que estamos construyendo bienvenido sea. Lo que sí resulta un poco molesto es que a este discurso se le de el nombre de arquitectura y más aún que se le incluya el epíteto de hexagonal.

Con frecuencia me siento peregrino en tierra de infieles cuando reclamo recurrentemente la necesidad de hacer un uso adecuado del lenguaje. Me he encontrado con muchos informáticos que se jactan de ser técnicos todo terreno muy competentes y para los que estos debates les resultan bizantinos e inocuos. Pero Wittgenstein ya hace muchos años que nos lo advirtió [5].

El pensamiento es una representación de la realidad. La realidad es aquello que se puede describir con el lenguaje, por eso los límites de mi lenguaje son los límites de mi mundo.

En este sentido, y suscribiendo la importancia de un uso correcto del lenguaje para no volvernos locos, podemos argumentar que las arquitecturas hexagonales no son ni arquitecturas ni hexagonales:

  • La arquitectura que no lo era. Una arquitectura de software establece una colección de restricciones estructurales que condicionan la anatomía, funcionamiento e interacción entre las partes de un producto software [6]. Así por ejemplo, en los aplicativos monolíticos, las arquitecturas por capas [7] promueven la idea de que el software debe articularse en base a una colección de capas de código que se responsabilizan de distintos aspectos transversales, tales como la presentación de datos, el control de la interacción o la integración con fuentes externas y donde la restricción fundamental estriba en que cada componente dentro de una capa sólo puede hablar con sus capas adyacentes. Por su parte, las arquitecturas MVC [8] estresan la importancia de mantener completamente separados en artefactos independientes la lógica de negocio, la lógica de presentación y la lógica de control como intermediador entre ambos. Las arquitecturas de pipes & filters [9] se basan en el diseño de canales de transformación funcional por los que se procesan datos bajo la hipótesis de que dichas transformaciones nunca pueden depender del estado interno. Y así podríamos seguir describiendo distintos tipos de arquitecturas que se han empleado con éxito a lo largo de la historia en los procesos de desarrollo. Todos estos modelos se ajustan a la definición anterior: restricciones estructurales que condicionan el funcionamiento y las dependencias entre las partes Las arquitecturas hexagonales promueven la idea de desacoplamiento pero, ¿cuál es su propuesta en relación con la organización estructural del código? Si se leen los artículos con atención observamos que no existe propuesta alguna lo que conduce a pensar que este modelo no es una arquitectura sino una colección de buenas prácticas.

  • El hexágono que no lo era. Quizá para salvar los muebles del problema de desestructuración que acabamos de describir, el autor originalmente pensó que sería buena idea afirmar que este tipo de arquitecturas tiene una morfología hexagonal y que están basadas en el uso de puertos y adaptadores. Afirmar esto último es poco menos que no decir nada ya que toda arquitectura está basada en procesos de composición de código y estos se pueden en esencia interpretar en términos de conectores y adaptadores. Pero quizá lo más escandaloso respecto a la propuesta es la afirmación anterior de que las arquitecturas son hexagonales. El mismo autor reconoce que el número de flancos en torno a los cuales puede articularse el desacoplamiento basado en puertos y adaptadores es irrelevante por cuanto a la postre depende de las particularidades del problema. Por tanto la hexagonalidad también queda en entredicho.

Advirtiendo esta doble preocupación que señalamos aquí, el autor se apresura a reconocer que, en realidad, las arquitecturas hexagonales pueden formularse como un patrón de diseño conocido como puertos y adaptadores [10]. Puestas así las cosas tal vez el problema lingüístico se amortigua. Las arquitecturas no son el vehículo para prescribir una colección de buenas prácticas en relación a los procesos de diseño porque para eso están los patrones de diseño. Pero en sentido estricto, la propuesta tampoco tiene anatomía de patrón ya que los patrones proporcionan soluciones probadas para problemas específicos recurrentes y el carácter de universalidad que se le pretende dar al modelo arquitectónico resulta ir en contra de esta idea. Pero en fin, seamos concesivos al respecto.

Asumiendo que este tipo de arquitecturas no arquitectónicas con morfología hexagonal de cualquier número de aristas son en realidad un patrón de diseño, merece la pena discutir ahora si verdaderamente aportan prescripciones de novedad en relación a los procesos de construcción de soluciones de software. A este respecto el panorama tampoco es muy halagüeño. Para demostrar que, en efecto, no se reporta novedad alguna en la propuesta, contrastemos lo que propone el modelo en relación a los 5 principios de diseño clásicos y esenciales de software orientado a objetos. Los archiconocidos principios SOLID [11]:

  • Principio de Responsabilidad Única. El principio de responsabilidad única establece que en una arquitectura de objetos, todo artefacto debe cubrir una única responsabilidad, o por decir mejor, una única razón para el cambio evolutivo. Parece que las arquitecturas hexagonales promocionan esta idea en base al ejercicio de descomposición modular que sugieren al distribuir las responsabilidades en torno a un hexágono de cualquier número de aristas.
  • Principio Abierto Cerrado. El principio abierto cerrado establece que todo software orientado a objetos debe estar funcionalmente preparado para operar correctamente pero abierto a posibles extensiones en versiones futuras. Dentro de las arquitecturas hexagonales tal principio se consigue por medio del uso de los puertos y adaptadores. En efecto, si en un momento determinado deseamos cambiar o extender una dependencia sólo tenemos que crear un nuevo adaptador para conectarlo al puerto correspondiente sin que eso implique cambio alguno en el núcleo funcional de la arquitectura.
  • Principio de Sustitución Liskoviana. Este principio establece que dentro de las arquitecturas orientadas a objetos deben definirse puntos de extensión lo suficientemente abstractos como para que puedan realizarse remplazos dinámicos sobre dichos puntos por artefactos semánticamente equivalentes. Ello se hace con el ánimo de adaptar el comportamiento sistémico sin implicar modificaciones generales en la arquitectura. El modelo hexagonal tiene una representación precisa de esta idea en la definición de puertos y adaptadores. Cada puerto es exactamente un punto de extensión liskoviana y cada adaptador una variante de sustitución.
  • Principio de Segregación de Interfaces. Con miras a la reutilización de código, el principio de segregación de interfaces promueve la idea de que toda abstracción de datos que se decida incluir en el ámbito de una solución orientada a objetos debe responder a una implementación de diferentes contratos que cubren aspectos ortogonales en relación a la responsabilidad de tal abstracción. Aunque este driver se cubre de una manera menos explícita en las arquitecturas hexagonales podemos asumir que la definición de los puertos se realice de acuerdo a estas ideas de segregación.
  • Principio de Inversión de Dependencias. Y finalmente, el principio de inversión de dependencias establece en toda solución orientada a objetos, cualquier colaboración entre los mismos debe articularse a un mismo nivel de abstracción y nunca desde un nivel más alto a uno más bajo. En este sentido, los algoritmos se expresan como colaboraciones abstractas que luego se concretan en términos de sustituciones liskovianas con las diferentes variantes que encontremos implementadas en el espacio de la solución, tal como comentábamos anteriormente. El proceso de desacoplamiento masivo que promueven las arquitecturas hexagonales va exactamente en esta dirección ya que cada puerto es un punto de extensión definido en términos abstractos a partir del cual se expresan las colaboraciones algorítmicas que orquesta el cuerpo funcional aislado de nuestro aplicativo.

Las voces más optimistas estarían tentadas a pensar que con todo lo anterior se demuestra que las arquitecturas hexagonales son una propuesta de valor por cuanto dan cobertura a cada uno de los cinco principios fundamentales del desarrollo de soluciones de software orientado objetos. No obstante, no debemos perder el rumbo. Lo que estábamos aquí discutiendo es si realmente este tipo de arquitecturas suponen una verdadera contribución novedosa para la comunidad de desarrolladores. A esa respecto hemos de reconocer que no existen contribuciones significativas más allá de un escrupuloso respeto a los 5 principios SOLID que todo buen desarrollador y arquitecto ya debería conocer y aplicar de forma sistemática.

En resumen, el nombre de arquitectura hexagonal es bastante desacertado y los contenidos de novedad bastante escasos. Pero lo que realmente resulta frustrante del artículo fundacional [3] es que la propuesta arquitectónica se compara con el modelo arquitectónico clásico de tres capas que ha demostrado su validez a lo largo de más de 20 años [12] [13]. Ya sabemos que las comparaciones son odiosas pero no tienen nada de malo en el ámbito técnico. Lo que sí resulta imperdonable es que se hagan con la imprecisión estratégica necesaria para sesgar la comparación claramente a favor de la nueva arquitectura que está proponiendo el autor. Se dice que las arquitecturas hexagonales garantizar el mantenimiento y la reutilización en base a un desacoplamiento sistemático y ello se compara con una arquitectura por capas donde dicho desacoplamiento no se practica. Efectivamente, las arquitecturas de tres capas no defienden el desacoplamiento de manera explícita pero eso es porque entienden que no es su competencia realizar tal prescripción. Esta advertencia ya queda claramente establecida en el principio de inversión de dependencias al que antes hacíamos referencia.

Lamentablemente, el sentido común es el menos común de los sentidos y todo parece indicar que la idea de la hexagonalidad arquitectónica es algo que ha llegado para quedarse. Grandes gurús, sin demasiados escrúpulos wittgensteinianos ya la entienden como parte del acerbo y la han incluido en su jerga habitual promoviendo su uso en determinados contextos arquitectónicos como es el reciente caso de las soluciones basadas en microservicios [14]. Así que poco queda por decir, quizá yo mismo me encuentre dentro de unos meses hablando en estos términos. Pero por lo menos aprovechemos este momento para reflexionar y hacer constar en acta que hay una nueva arquitectura hexagonal que ni es nueva, ni es arquitectura, ni es hexagonal. Mientras esto quede en el background común, el pragmatismo de Wittgenstein [15] no nos señalará con el dedo.

Eso sí, para futuros experimentos un ruego a la comunidad: por favor, en lo venidero más academia y menos patrón que no lo es.

Deja tu comentario