¿Qué es la Arquitectura de Software?

¿Qué es la Arquitectura de Software?

Antes de profundizar en la Arquitectura Hexagonal, aclaremos qué es la Arquitectura de Software. Hay muchos expertos famosos en el mundo del software que han creado sus propias definiciones sobre Arquitectura de Software.

Grady Booch, Un importante contribuyente a la industria del software que codesarrolló el lenguaje de modelado UML, se refirió a la ella como “la que representa las decisiones importantes que dan forma a un sistema, donde la importancia se mide con el costo del cambio”.

Ralph Johnson, un miembro de la Gang of Four y coautor de uno de los libros de informática más influyentes, Design Patterns: Elements of Reusable Object-Oriented, la definió así:

“La arquitectura se trata de las cosas importantes... sean las que sean”.

Hay muchas más descripciones y hasta ahora parece que no tenemos un consenso sobre la definición de Arquitectura de Software entre los expertos en el espacio del software.


Los pilares de la Arquitectura de Software

Aunque parece imposible ponerse de acuerdo sobre una definición consolidada de Arquitectura de Software, definitivamente podemos hablar de sus ingredientes principales .

Neal Ford y Mark Richards, en su gran libro Fundamentals of Software Architecture: An Engineering Approach, crearon cuatro dimensiones que conforman la arquitectura del software. Me gusta llamarlos Pilares de la arquitectura del software.

Estrutura do Sistema

Características da Arquitetura

Decisões de Arquitetura

Princípios de Design

Isso se refere ao estilo ou padrão através do qual o sistema é implementado, como Microsserviços, Orientado a Eventos, em Camadas, etc.


Atributos de qualidade, conhecidos como “ilities” ou requisitos não funcionais do sistema, como escalabilidade, flexibilidade, disponibilidade, etc. Eles não exigem conhecimento da funcionalidade do sistema, mas são necessários para que o sistema funcione corretamente. Eles são um aspecto crucial da arquitetura porque podem direcionar o sistema para uma estrutura específica (padrão).

Estas são as regras rígidas para a construção de sistemas. São restrições que impactam o desenvolvimento do sistema e geralmente tratam do que não é permitido. Um exemplo de decisão arquitetural seria restringir o acesso ao banco de dados de todas as camadas, exceto a camada de serviço (em uma arquitetura em camadas típicas)


Ao contrário das decisões arquiteturais, os princípios de design são algumas diretrizes sobre como o software deve ser construído, em vez de regras rígidas.


¿Qué es la Arquitectura Hexagonal?

La arquitectura hexagonal es un estilo arquitectónico de propósito general que tiene como objetivo crear software desacoplado. Como afirma el propio autor, el Dr. Alistair Cockburn:

“Permite que una aplicación sea impulsada por igual por usuarios, programas, pruebas automatizadas o secuencias de comandos por lotes, y que se desarrolle y pruebe de forma aislada de sus eventuales dispositivos de ejecución y bases de datos”.

Este estilo arquitectónico también se conoce como Puertos y Adaptadores, y esto se debe a que son las propiedades principales de este patrón. La idea clave es separar la lógica empresarial central de las preocupaciones externas, como bases de datos, marcos web, colas de mensajes, etc., para que la aplicación en sí no dependa de ninguna tecnología específica. La regla general es que nada entra ni sale nada sin pasar por las puertas.

La historia de la Arquitectura Hexagonal

La separación de las reglas de negocio de las preocupaciones periféricas se remonta a principios de la década de 1990, específicamente en el método basado en casos de uso de Ivar Jacobson. Inicialmente, el patrón de Jacobson se llamó EIC (Entity-Interface-Control). Brevemente, el término "límite" reemplazó a "interfaz" para evitar una posible confusión con la terminología del lenguaje de programación orientado a objetos. Otros patrones similares a la Arquitectura Hexagonal son Onion Architecture de Jeffrey Palermo e Clean Architecture de Robert C. Martin.

Si bien todos presentan sus propios conceptos, todos también utilizan el principio de inversión de dependencia, que establece que los módulos de alto nivel (reglas comerciales) no deben depender de módulos de bajo nivel (módulos específicos de tecnología); ambos deben depender de abstracciones. Las abstracciones no deberían depender de los detalles. Los detalles deben depender de abstracciones.

Este principio es propuesto por Robert Martin, quien describe que al seguir este principio, las dependencias del código fuente se pueden invertir y no verse obligadas a alinearse con el flujo de control. Con la capacidad de invertir las dependencias del código fuente, obtienes control absoluto sobre la dirección de las dependencias del código fuente de tu sistema.


Puertos

Podemos ver un puerto como un punto de entrada independiente de la tecnología; determina la interfaz que permitirá a los actores externos comunicarse con la aplicación, independientemente de quién o qué implementará esa interfaz. Al igual que un puerto USB permite que varios tipos de dispositivos se comuniquen con una computadora, siempre que tengan un adaptador USB.

Los puertos también permiten que la Aplicación se comunique con sistemas o servicios externos, como bases de datos, intermediarios de mensajes, otras aplicaciones, etc.

Consejo profesional: una puerta siempre debe tener dos elementos vinculados, uno de los cuales siempre es una prueba.

Adaptadores

Un Adaptador iniciará la interacción con la aplicación a través de un puerto, utilizando una tecnología específica, por ejemplo, un controlador REST representaría un adaptador que permite a un cliente comunicarse con la aplicación. Pueden existir tantos adaptadores para un solo puerto como sean necesarios, sin que esto suponga un riesgo para los puertos ni para la propia aplicación.


Aplicación

La Aplicación es el núcleo del sistema, contiene los servicios de la aplicación, que organizan la funcionalidad o los casos de uso. También contiene el Modelo de Dominio, que es la lógica de negocios integrada con Agregados, Entidades y Objetos de Valor (Value Objects).

La aplicación está representada por un hexágono, que recibe comandos o consultas de los puertos y envía solicitudes a otros actores externos, como la base de datos, también a través del puerto. Cuando se combina con el diseño basado en dominio (Domain-Driven Design), la Aplicación o hexágono contiene las capas de aplicación y dominio, dejando fuera las capas de Interfaz de Usuario e Infraestructura.

Lado Conductor x Lado Dirigido (Driving Side vs Driven Side)

Los actores protagonistas (o primarios) son los que inician la interacción y siempre están representados en el lado izquierdo. Por ejemplo, un adaptador de activación puede ser un controlador que recibe información (del usuario) y la pasa a la aplicación a través de un puerto.

Los actores dirigidos (o secundarios) son aquéllos “inducidos a comportarse” por la aplicación. Por ejemplo, la aplicación llama a un adaptador de base de datos para recuperar un conjunto particular de datos de la persistencia.

A la hora de implementar, hay algunos detalles importantes que no se deben olvidar:

  • Los puertos (la mayoría de las veces, dependiendo del idioma elegido) se representarán como interfaces en el código.
  • Los Driving Adapters utilizarán un puerto y un Servicio de Aplicación implementará la Interfaz definida por el puerto. En este caso, tanto la interfaz del puerto como la implementación están dentro del hexágono.
  • Los adaptadores impulsados ​​implementarán el puerto y un Servicio de Aplicación lo utilizará. En este caso, el puerto está dentro del hexágono, pero la implementación está en el adaptador, por lo tanto, fuera del hexágono.

Inversión de Dependencia en el contexto de la Arquitectura Hexagonal

El Principio de Inversión de Dependencia es uno de los 5 principios acuñados por (tío) Bob Martin en su artículo Design Quality Metrics y posteriormente en su libro Agile Software Development, Principles, Patterns and Practices, donde lo define de la siguiente manera:

  • Los módulos de alto nivel no deberían depender de módulos de bajo nivel. Ambos deben depender de abstracciones.
  • Las abstracciones no deberían depender de los detalles. Los detalles deben depender de abstracciones.

Como se mencionó anteriormente, los lados izquierdo y derecho del hexágono contienen 2 tipos diferentes de actores, Driving y Driven, donde existen puertos y adaptadores.

Del lado del Controlador, el adaptador depende del puerto, que es implementado por el Servicio de Aplicación, por lo que el adaptador no sabe quién reaccionará a sus invocaciones, solo sabe qué métodos se garantiza que estarán disponibles, por lo que depende de una abstracción.

En el lado Dirigido (Driven), el Servicio de Aplicación es el que depende del puerto y el adaptador es el que implementa la Interfaz del Puerto, invirtiendo efectivamente la dependencia ya que el adaptador de 'low-level' (es decir, el repositorio de la base de datos) se ve obligado a implementar la abstracción definida en el núcleo de la aplicación, que es el "nivel superior".

Conclusión

Existen muchas ventajas al utilizar la arquitectura de puertos y adaptadores, una de las cuales es poder aislar completamente la lógica de su aplicación y la lógica de dominio de una manera totalmente comprobable. Como no depende de factores externos, probarlo se vuelve natural y el mocking de sus dependencias es fácil.

También permite diseñar todas las interfaces de tu sistema "por propósito" y no por tecnología, evitando que se quede estancado y facilitando que la pila tecnológica de tu aplicación evolucione con el tiempo. Si necesitas cambiar la capa de persistencia, adelante. Si necesitas permitir que los robots de Slack en lugar de los humanos llamen a tu aplicación, ¡no hay problema! Todo lo que tienes que hacer es implementar nuevos adaptadores y listo.

La arquitectura hexagonal o de puertos y adaptadores no es la solución mágica para todas las aplicaciones. Implica un cierto nivel de complejidad que, cuando se maneja con cuidado, aportará grandes beneficios a su sistema.

Cuando se implementa adecuadamente y se combina con otras metodologías, como Domain-Driven Design, puertos y adaptadores pueden garantizar la estabilidad y extensibilidad a largo plazo de una aplicación, agregando mucho valor al sistema y a la empresa.

💡
Las opiniones y comentarios emitidos en este artículo son propiedad única de su autor y no necesariamente representan el punto de vista de Listopro.

Listopro Community da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.