Historia de una integración (ii): La arquitectura


El inicio de un proyecto siempre es un pequeño caos. Donde no había nada, ahora hay una multitud de cosas por hacer. Entre ellas, definir la arquitectura de la aplicación con la que guiar el posterior desarrollo. Para obtener la información necesaria, de forma paralela se debe iniciar también el análisis de los requisitos y contexto del proyecto.

La aplicación

La aplicación de esta historia -os recuerdo- es un front-end web Java que permite realizar acciones concretas sobre varios módulos de un sistema SAP.

Para no aburrir, resumiré los requisitos y el contexto del proyecto en
  • (i) aplicación dividida en módulos (uno por cada módulo SAP más un módulo Administración),
  • (ii) integración mediante webservices SOAP,
  • (iii) multiples servicios y todos, inicialmente, sin desarrollar ni definir su interfaz,
  • (iv) pantallas basadas en formularios web y tablas RIA,
  • (v) dos pantallas más complejas basadas en un potente grid de datos que permita manejar una gran cantidad de registros (alrededor de 200) sin paginación, ordenación por todas las columnas, modificación de algunos campos de forma inline y multiselección para ejecutar acciones sobre los registros seleccionados,
  • (vi) mantenimiento de una réplica sincronizada en base de datos de la estructura de centros y catálogo de materiales de SAP,
  • (vii) elevado número de usuarios, varios miles registrados, con picos de más de cien usuarios conectados simultaneamente,
  • (viii) ejecutable en IE6 y
  • (ix) equipo de desarrollo con dedicación parcial y formado principalmente en Hibernate y Struts.

Principios

La experiencia me ha enseñado la importancia de unas pocas reglas básicas que he convertido en los principios sobre los que procuro diseñar y desarrollar mis proyectos. Son estos:
  • Simplicidad (KISS, Keep it simple, stupid). En realidad una aplicación web no es nada compleja. Normalmente basta con aplicar el patrón de diseño MVC más una lógica y ordenada estructura de paquetes y clases. Y si la cosa se complica, no tener miedo de realizar los refactoring necesarios para volver a tener la complejidad controlada.
    Cuidado con la sobreingeniería. No te vuelvas loco con los patrones GoF si no estás creando un framework. Para una aplicación son más importantes los patrones GRASP.

  • Reutiliza, no repitas (DRY, Dont repeat yourself). Mucho cuidado con el copypaste y con el código pegamento y boilerplate. Utiliza detectores de código duplicado (pej. Checkstyle y PMD), crea componentes reutilizables y usa clases template para evitar el código boilerplate. El ejemplo más típico y dañino sería la gestión de conexiones y transacciones en base de datos.

  • Reutiliza, no reinventes (evita el sindrome NIH, Not invented here). Apache, Springsource, Eclipse, JBoss, Codehaus, Sun,... ¿de verdad no existe una solución éficaz a tu problema ya creada, documentada, probada y mantenida?

  • Diseña software facilmente testeable (TDD, Test Driven Design). Al menos las capas de negocio y datos deben poder ser probadas de forma sencilla, automatizada y sin necesidad de desplegar la aplicación en un servidor. No confundir con la metodología Desarrollo guiado por pruebas.

La arquitectura

La aplicación utiliza una arquitectura en N capas, estructurada en las capas de (i) integración con SAP, (ii) acceso a base de datos, (iii) lógica de negocio o middleware y (iv) presentación. A continuación pasaré a describir cada una de las capas y las tecnologías utilizadas en ellas.

Integración con SAP

El sistema SAP contaría con un XI, o infraestructura de intercambio, donde estarían definidos los distintos servicios web que usaría nuestra aplicación para realizar acciones concretas en los módulos SAP implantados.

Es la capa más importante. Al fin y al cabo es un proyecto de integración. No podía haber fallos ni improvisaciones. Así que para implementar los clientes webservices decidí usar Axis2. Es un framework que conozco muy bien, destaca por su madurez, rendimiento y sus altas capacidades de configuración y compatibilidad con casi todos los OXMs (Mapeador Objeto-XML) existentes.

Acceso a base de datos

La aplicación debía contar con su propia base de datos para la gestión de usuarios, datos propios y mantener una réplica sincronizada periódicamente de la estructura de centros y el catálogo de materiales gestionado en SAP.

A pesar de que el catálogo era enorme (cerca de 100 mil registros), el schema en sí no iba a contar con muchas tablas y era bastante sencillito. Por lo que el Oracle9 del cliente no iba a ser ningún cuello de botella.
Así que no ví mayor problema en usar Hibernate, con la esperanza de que nuestro supuesto dominio en él nos permitiera despreocuparnos relativamente de esta capa y ganar tiempo de desarrollo.

Middleware

Para implementar la capa de lógica de negocio no tuve muchas dudas, Spring como framework principal y dominante. Spring permite (i) integrar el resto de tecnologías que ibamos a usar y (ii) cumplir con los principios antes comentados, ambos de forma natural y sencilla. Además de aportar su motor de inyección de dependencias y sistema de AOP. En mi opinión, características básicas de cualquier desarrollo enterprise.

También hemos utilizado Spring Security como solución de seguridad, Quartz para las tareas programadas, la útil Commons Lang y el binomio Commons Logging/Log4j para el logging.

Presentación

Intentaré ser breve, como framework web decidí usar Struts1 (los motivos más abajo) para controlar la navegación hasta las pantallas principales.

Como sistema de plantillas para las pantallas, otro veterano, Tiles. Usar un sistema de plantillas es básico para mantener lo más simple posible las distintas jsps que formaban cada pantalla.

Dentro de cada pantalla está prohibido usar código Java, usamos Jakarta Taglibs como librería de etiquetas implementación de la estupenda especificación JSTL, la última gran especificación.

La parte RIA viene en 2 sabores, DWR y jQuery. DWR es un framework Ajax no muy conocido que permite invocar métodos de clases Java de la aplicación desde código Javascript en el navegador cliente. Es potentisimo, sencillo y muy configurable. Además cuenta con soporte para Reverse Ajax.

Mientras que JQuery aporta toda la magia visual con su legión de plugins y el tan necesario toque cross-browser. Destacar los widgets de jQuery UI y los plugins jQuery Validation y jQuery Grid.

Alternativas desestimadas

Ahora lo leo y parece sencillo. No lo fue. Dejaré las valoraciones para otro día...
Lo que sí voy a hacer es nombrar algunas alternativas que descarté durante el proceso de diseño y porqué.
  • Cualquier otro framework web. Sí, ya sé que Struts1 está pasadísimo, más muerto que SOA y el propio Java juntos, y hay otros frameworks web mejores. Pero eso no lo convierte en un mal framework y es él que domina mi equipo y yo mismo. Tampoco había tiempo para aprender otro y aunque lo hubiera, personalmente, no tengo claro cúal debería ser su sucesor, ¿Struts2, Spring MVC, GWT, Seam, JSFs, Wicket,...?
    Como ya he dicho sólo lo ibamos a usar para la navegación, así que nos sobraba.
  • OSGI. Sí es una aplicación modular, pero en realidad la necesidad de activar y desactivar módulos es practicamente nula.
  • JPA. ¿Para qué? Si vamos a usar Hibernate y punto. Y encima con características específicas como el Criteria o el delete_orphan. IMHO esta especificación llega tarde y además mal.
  • Ext-Js. No sólo es una delicia visual, es realmente eficiente en comparación con el resto de clones que han ido saliendo. De hecho, lo estabamos evaluando en otro proyecto más pequeño cuando nos pilló el cambio de licencia. Ahora usamos jQuery y estamos más que contentos.

Así que ya teniamos el entorno de desarrollo y el diseño general de la aplicación definidos. Era el momento de empezar el desarrollo. Pero eso ya será otro post...

7 comentarios :: Historia de una integración (ii): La arquitectura

  1. Buena elección tecnológica. Son todo herramientas sobradamente probadas y MUY IMPORTANTE con una masa de usuarios grande que permite resolver dudas y problemas en LA INTERNET!!!.

    Hecho de menos Spring, sobre todo a la hora de la realización de Test. Con spring todas las capas están mucho más próximas al main.

    Con respecto a Struts 1 estoy contigo. Es estúpido cambiar de tecnología cuando una cumple sobrádamente los objetivos y además la controlamos sobradamente. También es verdad que yo últimamente me he pasado a Spring MVC, pero sólo por comodidad, no porque me aporte nada especial.

    Saludos.

  2. Bastante de acuerdo con todo lo que has dicho.

    Solo una nota: el año pasado di carpetazo a Axis y comencé con Spring WS. Conclusión: Actualmente lo considero uno de los mejores módulos de Spring.

  3. @xx Creo que has debido saltarte la capa middleware que es donde usamos Spring. He preferido dejar el tema del testing para la parte de desarrollo, pero vas bien encaminado. En realidad con Spring todo es más fácil y eso se agradece.

    @angelborroy gracias por el feedback sobre Spring WS. Lo cierto es que lo estuve pensando, pero no me atreví a probarlo en este proyecto. Demasiado arriesgado.

  4. A pesar que tiene Struts 1 , está bien integrado

  5. Y DDD?

  6. @CDavid: DDD nada. Lo cierto es que nunca lo he usado y éste no era un proyecto para andarse con probaturas.
    Además en realidad tampoco es una aplicacion CRUD típica de intranet que es donde yo más veo que es el objetivo de DDD y derivados. Es una aplicación enterprise de integración mediante webservices SOAP.

  7. dejo un link sobre un articulo que trata sobre un caso practico utilizando los patrones GRASP y GoF http://oscar-sandoval.blogspot.com/

Publicar un comentario