¡Actualización! 🎉 Aquí la introducción a Domain-Driven Design o DDD que, tras algún tiempo y aprendizajes que queremos compartir después de este post sobre Arquitectura Hexagonal 😊
Hoy sentaremos los principios sobre la Arquitectura de Software y, más en concerto, sobre qué es la Arquitectura Hexagonal. Tras una primera temporada donde hemos hablado al respecto de los principios SOLID, y hemos visto los problemas del código acoplado en términos de testabilidad, vamos a pasar a dar un salto en cuanto al diseño de Software y nos centraremos en la Arquitectura de Software, o como lo denominaba Sandro Mancuso: "Macro-design".
Arquitectura de Software
En este vídeo hablaremos sobre la Arquitectura Hexagonal, pero antes, introduciremos el concepto de Arquitectura de Software y justificaremos en qué contexto sería necesario plantear una estrategia a seguir al respecto. Nos apoyaremos en el concepto de Complejidad Accidental vs. Complejidad Esencial para justificar la necesidad de plantear unas reglas de juego a la hora de diseñar Software que nos permitan mantener la Complejidad Accidental a raya.
Clean Architecture
Después de introducir el concepto de Arquitectura de Software, hablaremos de las "arquitecturas limpias" (😅) o Clean Architecture. Éstas son un tipo de arquitectura que, como plantea Uncle Bob, establecen una serie de delimitaciones en cuanto a las capas de nuestra aplicación, y proponen una regla de dependencia entre ellas que va de fuera hacia dentro. De esta forma, conseguimos evitar el acoplamiento de nuestro dominio con elementos más externos, hecho que nos permitirá una alta tolerancia al cambio. Es interesante explorar este concepto y ver que es algo completamente agnóstico al tipo de aplicaciones. Si bien es cierto que dependiendo de si estamos haciendo una aplicación móvil o una API REST, tendremos que tener en cuenta ciertos aspectos concretos de nuestro contexto, en un nivel de abstracción como el que se plantea cuando hablamos de Clean Architecture, podemos encontrar grandes puntos en común. Tanto es así que aquí podéis ver un ejemplo de aplicación de Clean Architecture en Android, en iOS, o en PHP.
Layers architecture
Antes de entrar en materia al respecto de la Arquitectura Hexagonal, cabe destacar la diferencia con la arquitectura en capas o "Layers architecture". Tal y como podemos ver en la imagen anterior, la arquitectura en capas tendría como centro la base de datos. Es decir, el dominio sería conocedor del sistema de persistencia y, por tanto, estaría acoplado a éste. Éste patrón lo vemos inevitablemente cuando hablamos de aplicaciones basadas en Active Record. Podemos encontrar este tipo de aplicaciones de forma bastante extendida en el mundo Ruby on Rails ya que, por defecto, es lo que nos propone este framework.
Por contra, en la Arquitectura Hexagonal (también llamada Ports and Adapters), tal y como podemos ver en la imagen anterior, la base de datos se concibe como uno más de los puertos con los que nuestro dominio interactúa. No obstante, para llevar a cabo esta interacción, siempre estaríamos aplicando el Principio de Inversión de Dependencias de tal forma que no nos acoplaríamos a la implementación en concreto del cliente de base de datos, si no a una interface (contrato) que sí residiría dentro de nuestro dominio.
Arquitectura Hexagonal
¿Por qué Hexagonal? Sinceramente, prefiero el nombre alternativo "Ports and adapters" o "Puertos y adaptadores".
- No induce a error al pensar en posibles limitaciones de 6 capas (por lo del hexágono).
- Incorpora el concepto de "puerto" a nivel teórico, extrapolable fácilmente al concepto de interface a nivel de implementación.
- Añade el concepto de "adapter", patrón de diseño usado ampliamente al aplicar el DIP.
¿Qué tiene que ver con el Domain-Driven Design (DDD)? Al ser una arquitectura que fomenta el que nuestro dominio sea el núcleo de todas las capas, y que no se acople a nada externo, encaja muy bien con la idea del DDD. Al fin y al cabo, la parte táctica del Domain-Driven Design no es más que la agrupación de muchos conceptos y patrones de diseño ya existentes. Así entonces, podríamos decir que el DDD se basa en la Arquitectura Hexagonal como pilar central en términos de arquitectura. ¿Qué beneficios tiene? Principalmente y fundamentado en el hecho del desacoplamiento, tenemos beneficios directamente en forma de:
- Alta testabilidad (Aplicación del Principio de Inversión de Dependencias (DIP) de SOLID para la interacción del dominio con el resto de elementos)
- Alta tolerancia al cambio (Principio de Abierto/Cerrado (OCP) de SOLID derivado de la aplicación del DIP)
- Alta reutilización de código debido a la división estricta de responsabilidades a nivel de Application Services y Domain Services (Principio de Responsabilidad Única (SRP) de SOLID)
A su vez, también cabe destacar el hecho de que, al estar basada en los contratos establecidos por los puertos que definamos, nos permite postponer decisiones a nivel de implementación (qué adaptador implementaremos para ese puerto). Esto facilita el desarrollo dirigido por test (TDD) ya que nos podemos centrar en la clase que estamos desarrollando sin necesidad de implementar sus colaboradores en ese estricto momento. Os recomiendo el post de Eduardo Ferro al respecto: El arte del patadon pa'lante / Postponer decisiones técnicas. Sin más, aquí el vídeo:
En futuros vídeos iremos desgranando cada una de las capas de esta arquitectura y entraremos más en materia a través de ejemplos de código. Así entonces, si ya os surgen dudas, plantearlas sin problema en los comentarios de este vídeo y así las podremos atacar en los siguientes :D. Por último, también os dejo el enlace al post que comento en el vídeo de Fideloper, un buen recurso para empezar a trastear con este tema :"