Activiti BPM: Primera toma de contacto
Hoy tendremos nuestra primera toma de contacto práctica con la implementación de procesos BPM usando el API de Activiti.
Fuente: http://blog.kennardconsulting.com/2011_05_01_archive.html
Con esto se persigue implementar la lógica de negocio (el núcleo) de forma aislada e independiente de cualquier agente externo. Los puertos y adaptadores son los puntos de entrada, salida y conversión de datos. Existirá un adaptador para cada agente externo: un adaptador para la interfaz de usuario (UI), otro para la persistencia, otro para la ejecución de tests, otro para la comunicación con otros servicios, etc. De esta manera se consiguen sistemas más reutilizables, más modulares y más mantenibles. Y la forma de conseguir este desacoplamiento es a través del principio de inversión de dependencias (del cual ya hablé con mayor profundidad en este artículo.
Crea tu aplicación para que funcione sin interfaz de usuario ni base de datos, únicamente para que pueda ser ejecutada por pruebas automáticas de regresión.
Sin embargo, este concepto por sí solo, se me antoja demasiado abstracto. La arquitectura hexagonal no establece ningún tipo de regla estructural de código. Tampoco plantea restricciones de interacción entre componentes. ¿Un componente de UI puede comunicarse directamente con un componente de persistencia? ¿o debe hacerlo a través del núcleo? Quizás deberíamos asumir todo esto como un marco conceptual o conjunto de buenas prácticas más que como una arquitectura propiamente dicha. Te invito a leer este interesante y crítico artículo al respecto.
En 2008 Jeffrey Palermo introduce un nuevo concepto al que llama “Onion Architecture”.
El propio autor lo define como “un patrón arquitectónico” que pretende evitar uno de los mayores inconvenientes del uso de las tradicionales arquitecturas de tres capas: el acoplamiento entre las capas. Según Jeffrey el enfoque tradicional crea sistemas donde la interfaz de usuario no puede funcionar sin la lógica de negocio, y la lógica de negocio no puede funcionar sin el acceso de datos. Y como consecuencia la interfaz de usuario está acoplada al acceso a datos.
Para evitar éstos acoplamientos propone una arquitectura basada en capas circulares a modo de cebolla. Todo este sistema de capas estará restringido por una regla fundamental: todo el código puede depender de las capas más centrales, pero no puede depender de las capas más alejadas del núcleo. Es decir, todo el acoplamiento es hacia el centro.
Fuente: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
Cada capa tendrá una responsabilidad concreta:
Núcleo de aplicación:
Modelo de Dominio: En el centro estará el modelo de dominio, que representa los objetos y estados de la organización.
Servicios de Dominio: Interfaces que definen comportamientos y operaciones sobre el modelo de dominio.
Servicios de Aplicación: Interfaces que definen comportamientos específicos de la aplicación.
Elementos Externos: En la parte más externa se encuentra la interfaz de usuario, la infraestructura y el sistema de pruebas. La capa exterior está reservada para las cosas que pueden cambiar más a menudo. Estas cosas deben estar aisladas del núcleo de la aplicación. Por ejemplo, aquí se implementarían las interfaces definidas en las capas de servicio. Estas implementaciones sí tendrán dependencias tecnológicas.
La arquitectura de cebolla se basa en estos cuatro principios:
Tanto la arquitectura hexagonal como la arquitectura de cebolla comparten la siguiente premisa: externalizar aspectos de infraestructura y la existencia de código de adaptación que permita independizar esa infraestructura.
Y por último, en 2012, Uncle Bob, en su ya famoso artículo introduce el concepto de “Clean Architecture”.
“La primera preocupación de un arquitecto es asegurarse de que la casa es utilizable, no asegurarse de que la casa está hecha de ladrillo.” (Uncle Bob)
Uncle Bob se da cuenta de que, en definitiva, todos estos conceptos y arquitecturas se fundamentan en una misma idea: la separación de capas. Y focaliza su atención en que todas coinciden en dos cosas: en considerar a la capa de lógica de negocio como el eje principal del sistema y en definir una serie de interfaces para comunicarse con el resto del sistema. Puedes llamarlo Dominio, Business Logic, Core, Application o como quieras, pero en cualquier caso esta capa es la más importante, la que maneja los hilos, y todo debe estar diseñado y modularizado en torno a ella. Así que Uncle Bob decide englobar estas propuestas en un único concepto al que denomina “Clean Arquitecture” y resume las características que debe tener un sistema construido con este tipo de arquitectura:
Independiente de frameworks. La arquitectura no debe depender de ningún framework ni librería cuyas características condicionen nuestro sistema a sus requisitos y restricciones. Los frameworks deben tomarse como herramientas de apoyo.
Testeable. La lógica de negocio se debe poder testear sin necesidad de ningún ajente externo (interfaz de usuario, base de datos, servidor web, etc.).
Independiente de la UI. La interfaz gráfica de usuario debe poder ser reemplazable con facilidad sin afectar al resto del sistema (por ejemplo, cambiar una UI web por una UI de escritorio, e incluso por una interfaz de consola, no debe suponer ningún cambio para la lógica de negocio).
Independiente de la base de datos. De forma similar a lo que sucede con la UI, la base de datos también debe ser fácilmente reemplazable. Las reglas del negocio deben permanecer ajenas al sistema de persistencia, le da igual que usemos Oracle, SQL Server, MongoDB o un simple sistema de ficheros.
Independiente de factores externos. En definitiva, la lógica de negocio no debe tener conocimiento directo de nada que provenga del mundo exterior (el modo de comunicación con otros sistemas -REST, SOAP, RMI, etc.-, el servidor donde se ejecuta -Wildfly, Glassfish, Tomcat, etc.-).
Siguiendo con su intención de unificar criterios, Uncle Bob integra todas estas arquitecturas en una sola idea representada por el siguiente esquema:
Fuente: https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html
Cada círculo representa un área del software:
Enterprise Business Rules: Área que encapsula la lógica de negocio a nivel empresarial. Aquí estarán los objetos, estructuras de datos y/o funciones que permiten modelar toda la lógica empresarial. Entidades del tipo Persona, Grupo, Pedido, Línea de Pedido, Factura, etc. formarán parte de esta capa. Ojo, no confundir con las Entities de JPA!!
Application Business Rules: Área que contiene las reglas de negocio específicas de la aplicación. Aquí se implementan los casos de uso que hace nuestra aplicación sobre las entidades empresariales. Mientras la capa anterior se ocupaba de los actores, ésta se ocupa de las interacciones (asociar una Persona como miembro de un Grupo, crear un Pedido con Líneas de Pedido…). Los cambios en esta capa no deberían afectar a las entidades, en cambio una modificación en las entidades si puede afectar a los casos de uso.
Interface Adapters: Área que contiene un conjunto de adaptadores donde se convierten datos entendibles por los casos de uso a datos aceptados por elementos externos, y viceversa. Por ejemplo, para comunicarse con la interfaz gráfica necesitaremos tener Presentadores que se encarguen de convertir objetos de nuestra lógica de negocio a objetos específicos del framework que estemos usando para la UI (JSF, Spring, Swing, Vaadin…). Con respecto al sistema de persistencia tendremos Repositorios que realicen esa adaptación en función del sistema de persistencia utilizado (ORMs, JPA, Hibernate, MyBatis…). Otro ejemplo serían los convertidores de servicios SOAP, o estructuras JSON, proporcionadas por algún servicio externo.
Frameworks y Drivers: Área más externa que se compone de frameworks y herramientas como la base de datos, el framework web, sistemas de testing, etc. Aquí van todos los detalles. La web es un detalle. La base de datos es un detalle. Mantenemos estas cosas fuera donde no pueden hacer mucho daño.
Y por último aquí indico algunas consideraciones, reglas y restricciones que plantea esta arquitectura:
Como podrás comprobar tampoco dice nada nuevo, pero si pone un poco de orden en toda esta idea del desacoplamiento a partir del principio de inversión de dependencias.
De momento, el concepto de “Clean architecture”, parece básicamente una recopilación de mejores prácticas basada en otros conceptos e ideas previas (y en la propia experiencia del autor). La principal mejora que parece haber aportado a la comunidad es una definición más detallada y precisa de las capas, reglas, restricciones, consideraciones y características que debe tener una arquitectura software para poder ser considerada “clean”.
Pero la palabra “clean” va mucho más allá, tanto como para escribir un libro. El señor Uncle Bob ya tiene en su bagaje éxitos como “Clean Code” o “Clean Coder”. Y ahora cierra la trilogía con el libro “Clean Architecture” donde, a parte de explicar con mayor profundidad lo visto en este post, dará respuesta a preguntas del tipo ¿cuáles son los principios básicos de la arquitectura de software?, ¿cuál es el papel de un arquitecto software?, ¿qué hace que una arquitectura vaya mal y qué podemos hacer al respecto? y un largo etcetera.
Bajo mi punto de vista la principal ventaja de este tipo de planteamientos es la de poder posponer decisiones tecnológicas, lo cual es una consecuencia de la modularización. Podremos comenzar a implementar el núcleo tan pronto como sepamos de qué va la aplicación. Imagina que comienzas un proyecto. Aún no está claro si será una aplicación Web o una APP para Smartphone. Tampoco se sabe si se quieren persistir los datos en un modelo relacional o NoSQL. Lo que sí se sabe es que tendrá que manejar usuarios, pedidos, facturas, un carro de la compra… ¡pues para qué esperar! empecemos a implementar el núcleo y vayamos ganando tiempo hasta que negocio se aclare.
Otra de las principales ventajas es poder minimizar el impacto de los cambios. Esto también es una consecuencia de la modularización, de tener todo bien separadito y las responsabilidades bien repartidas.
Por otro lado, hay que tener presente que una arquitectura de este tipo tiene sentido en aplicaciones grandes. En una aplicación pequeña y sin perspectivas de ampliación puede ser incluso contraproducente. No tiene sentido complicar las cosas más de la cuenta.
Deja un comentario