Arquitecturas basadas en componentes
Un artículo de Rafa G. Blanes
Actualmente estoy muy involucrado dirigiendo un proyecto en el que debemos desarrollar un framework corporativo para una compañía de fabricación de componentes aeronáuticos. El objetivo a medio plazo del proyecto consiste en que la compañía tenga los pilares fundamentales sobre los que construir toda la funcionalidad de tipo ERP y procesos de negocio, algo bastante ambicioso.
¿Qué tienen en común este proyecto (o las necesidades de esta compañía) en relación al sistema software que necesitan poner en marcha y otros similares? Me lo he encontrado en otras ocasiones: negocio que avanza rápido y cuyas necesidades también progresan de la noche a la mañana.
Por detallarlo mejor:
- Distintos perfiles de usuario deben acceder al sistema para utilizarlo según su rol (operarios de fabricación, directivos, ventas, recursos humanos, etc.)
- Todo debe estar integrado en un mismo proyecto que dé servicio a todos. Nada peor que necesitar un conjunto de aplicaciones dispersas e independientes entre ellas para darle de comer al negocio, de ese modo, imposible (o muy costoso) realizar cualquier tipo de analítica, la dirección no puede tener visibilidad real de los detalles del día a día, etc.
- Las necesidades cambian continuamente, debiendo incorporar más funcionalidad frecuentemente. Esto forma parte de la esencia del sistema.
- El negocio dependerá completamente de este sistema, lo que implica una gran responsabilidad (hablamos de millones de euros de facturación, glups...)
¿Cómo afrontar un desarrollo de este tipo?
Ya pasé por la experiencia de un proyecto con características similares en el que se planteó (en contra de mi criterio) una arquitectura demasiado "ad hoc" y monolítica para cubrir lo anterior, de modo que ante las necesidades anteriores, una mejor aproximación consiste en crear un sistema con una arquitectura basada en componentes (de ahí lo de framework corporativo) y cuyas tecnologías se usen lo más desacopladas posible (para un proyecto cuyo servicio debe durar muchísimos años, nada peor que vincularlo totalmente a un mismo repositorio de datos o tecnología web). En este caso, usamos .NET framework pero lo dejamos todo listo para utilizar .NET Core tan pronto como éste comience a estar más maduro (algo que sin duda ocurrirá a medida que se vaya implantando).
Esta arquitectura no es ninguna novedad: directa o indirectamente, muchas soluciones de mercado la siguen, desde CMS como Drupal (y su ampliación de funcionalidad mediante módulos) hasta la extensibilidad de funcionalidad de Alfresco. Es decir: existe un framework a modo de core que ofrece una funcionalidad base que se puede extender mediante plugins, extensiones, componentes o módulos (el nombre es equivalente, lo que importa es el concepto, aunque en el contexto de este artículo los denominaré a todos como "componente").
¿Qué hace ese framework base? Se encarga de lo siguiente:
- La gestión de usuarios (login, registro de actividad, altas, bajas, etc.).
- Todo lo relacionado con la seguridad (roles, permisos, autentificación, tokens para las APIs, etc.).
- Aisla del tipo de repositorio de datos utilizado (los componentes ni siquiera deberían saber que lo que hay detrás es un Sql Server, Sql Azure, MySql, Oracle, Redis o cualquier otro medio de persistencia de datos).
- Nivel de presentación: el framework se encarga del proceso básico de construcción de la interfaz de usuario (lo habitual es estar basado en alguna tecnología web).
- El framework ofrece una API mediante la cual se puede extender su funcionalidad mediante componentes: esta es una parte esencial y la razón de ser del framework.
- Debe permite activar, desactivar, instalar o desinstalar componentes en caliente.
- Permite añadir nuevos componentes al sistema sin necesidad de pararlo temporalmente, garantizando un funcionamiento 24/365 (salvo en actualizaciones del mismo framework, claro). Esto facilita un enfoque DevOps para la compañía.
- Asiste a los componentes cuando cambian de una versión a otra, para que la migración sea lo más fácil posible, así como la implementación de esa migración.
- Es escalable: varias instancias del framework pueden convivir en diferentes servidores como redundancia por seguridad y para soportar cargas altas de trabajo.
Fácil de decir pero no tan sencillo de implementar.
Por otra parte, y gracias a todo lo anterior, un componente puede:
- Añadir nueva funcionalidad al sistema (nuevas entidades de datos exportables, tareas recurrentes, eventos, nuevas vistas, nuevos informes, etc.)
- Un componente se debe poder implementar fácilmente, ya que gran parte del trabajo pesado lo realiza el framework. Debe existir una guía de desarrollo de componentes para que cualquier desarrollador pueda extender la funcionalidad.
- Un componente puede tener asociado una interfaz de usuario (mediante una vista o bloque que se renderizará de algún modo, esto es trabajo del framework)
- Puede definir sus necesidades de almancenamiento de información (pero sin ensuciarse con los detalles de creación de entidades, tablas, índices, etc. según el tipo de tecnología a usar; esto es trabajo del framework).
- Puede comunicarse con otros componentes.
De este modo, un sistema así está compuesto del mismo framework, un conjunto de componentes del mismo framework (core components) y otro conjunto de componentes de usuario (user components). En el caso en el que estamos trabajando, se llegará a tener con toda probabilidad más de cincuenta para conseguir toda la funcionalidad requerida.
Ni que decir tiene que en un proyecto de esta naturaleza, el framework tiene que ser una pieza software robusta y con una cobertura de tests muy alta, con un diseño impecable, limpio y mantenible.