Actualmente estoy muy involucrado dirigiendo un proyecto en el que debemos desarrollar un framework corporativo para una compañía que fabrica 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 los procesos de negocio; algo bastante ambicioso.
¿Qué tienen en común este proyecto (o las necesidades de esta compañía) con otros sistemas similares? Me lo he encontrado en otras ocasiones: negocios que avanzan 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 sí para darle de comer al negocio. De ese modo es imposible —o muy costoso— realizar cualquier tipo de análisis, y la dirección no puede tener visibilidad real de los detalles del día a día.
- Las necesidades cambian continuamente y hay que incorporar más funcionalidad con frecuencia. 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 las necesidades anteriores. Para un sistema de este tipo, una mejor aproximación consiste en crear una arquitectura basada en componentes (de ahí lo de framework corporativo) y utilizar las tecnologías de forma lo más desacoplada posible. Para un proyecto cuyo servicio debe durar muchísimos años, nada peor que vincularlo totalmente a un mismo repositorio de datos o a una única tecnología web. En este caso usamos .NET Framework, pero lo dejamos todo listo para utilizar .NET Core tan pronto como empiece 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 del mercado la siguen, desde gestores de contenido como Drupal (que amplía su funcionalidad mediante módulos) hasta la extensibilidad funcional 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 importante es el concepto, aunque en el contexto de este artículo los llamaré a todos «componentes».
¿Qué hace ese framework base?
Se encarga de lo siguiente:
- Gestionar usuarios (inicio de sesión, registro de actividad, altas, bajas, etc.).
- Todo lo relacionado con la seguridad (roles, permisos, autenticación, tokens para las API, etc.).
- Aislar del tipo de repositorio de datos utilizado. Los componentes ni siquiera deberían saber si detrás hay SQL Server, SQL Azure, MySQL, Oracle, Redis u otro medio de persistencia.
- Proporcionar el nivel de presentación: el framework se encarga del proceso básico de construcción de la interfaz de usuario, habitualmente basada en alguna tecnología web.
- Ofrecer una API mediante la cual se pueda extender su funcionalidad con componentes. Esta es una parte esencial y la razón de ser del framework.
- Permitir activar, desactivar, instalar o desinstalar componentes en caliente.
- Permitir añadir componentes nuevos al sistema sin necesidad de pararlo temporalmente, garantizando un funcionamiento 24/365 (salvo durante las actualizaciones del propio framework, claro). Esto facilita un enfoque DevOps para la compañía.
- Asistir a los componentes cuando pasan de una versión a otra, para que la migración sea lo más fácil posible, así como su implementación.
- Ser escalable: varias instancias del framework pueden convivir en diferentes servidores para proporcionar redundancia y soportar cargas de trabajo altas.
Fácil de decir, pero no tan sencillo de implementar.
Por otra parte, gracias a todo lo anterior, un componente puede:
- Añadir funcionalidad nueva al sistema (nuevas entidades de datos exportables, tareas recurrentes, eventos, vistas, informes, etc.).
- Implementarse 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.
- Tener asociada una interfaz de usuario mediante una vista o un bloque que se renderizará de algún modo: de eso se encarga el framework.
- Definir sus necesidades de almacenamiento de información, sin tener que ocuparse de los detalles de creación de entidades, tablas, índices, etc. según la tecnología utilizada: ese es el trabajo del framework.
- Comunicarse con otros componentes.
De este modo, un sistema así está compuesto por el propio framework, un conjunto de componentes del framework (core components) y otro conjunto de componentes de usuario (user components). En el caso en el que estamos trabajando, probablemente llegaremos a tener más de cincuenta para implementar toda la funcionalidad requerida.
Ni que decir tiene que, en un proyecto de esta naturaleza, el framework debe ser una pieza de software robusta, con una cobertura de pruebas muy alta y un diseño impecable, limpio y mantenible.