miércoles, 12 de diciembre de 2007

Model Driven Architecture en Java

Simplificando su definición, la metodología MDA (Model Driven Architecture, especificada por el OMG) propone definir la funcionalidad de las aplicaciones de forma abstracta, independientemente de tecnologías, por ejemplo con UML; y luego dada la especificación de alto nivel, se podría "traducir" la misma a una implementación concreta en Java o .NET mediante una herramienta automatizada.

Hay varias herramientas que siguen el paradigma MDA, la mayoría muy verdes en mi opinión, aunque si leemos las presentaciones prometen el paraíso, los proveedores le "ponen color" a sus productos, como decimos en Uruguay.

Por ejemplo, el año pasado evalué AndroMDA, es una herramienta que permite tomar un modelo UML y transformarlo en componentes deployables para plataformas como J2EE y .NET. También incluye un kit para desarrollar generadores de código o personalizar los existentes.

En un momento estuve cerca de empezar a usar AndroMDA en mi trabajo, pero no me pareció conveniente porque ya teníamos un esquema de desarrollo definido y la personalización de los templates no era sencilla, en ese momento no había documentación suficiente, como pasa en muchos de los proyectos open source.
Por lo tanto me basé en varios artículos sobre code generation para desarrollar algo in-house.

Si analizamos los cronogramas de los proyectos, veremos que dedicamos un tiempo considerable en implementar ABMs (Alta, Baja, Modificación), cuando por lo general es una funcionalidad accesoria. Lo realmente importante son los casos de uso que involucran procesos de negocio, por ejemplo registrar una transacción bancaria.
Basándome en la premisa anterior, lo natural era comenzar a estudiar la automatización del desarrollo de los mantenimientos.

Lo primero fue llegar a un ABM estándar (como el "Work With" de Genexus), por ejemplo con: búsqueda, ingreso, detalle, modificación y eliminación de usuarios; siempre tratando de estandarizar los nombres de los componentes (páginas JSP, clases Java, etc).

El siguiente paso fue identificar los lugares que hacían referencia a la entidad en juego, para así poder definir un template y usar expresiones en esos lugares.

Luego del ejercicio obtuvimos los siguientes componentes de software:

  1. Usuario.java: Clase del dominio que define los atributos del usuario, declara los mapeos de Hibernate mediante XDoclet.
  2. ABMUsuarioAction.java: Action de Struts con todas las operaciones.
  3. UsuarioForm.java: ActionForm de Struts con los mismos atributos que la clase de dominio.
  4. usuarioForm.jsp: Página de ingreso, detalle y modificación.
  5. usuarioList.jsp: Página con filtro de búsqueda y grilla de resultado con acciones.
  6. UsuarioServices.java: Interface que define los servicios de la entidad.
  7. UsuarioServicesImpl.java: Clase que implementa la interface de servicios.
  8. UsuarioDAO.java: Clase que implementa las operaciones sobre la base de datos.
Como primera aproximación, podríamos crear los archivos del 2 al 8 a partir de la clase de dominio usando introspection para descubrir los atributos de la entidad, por supuesto si usamos el estándar JavaBean para nombrar getter y setters.

Como template engine elegí Velocity, me pareció muy sencillo usar, tiene un lenguaje llamado VTL que incluye estructuras de control, operadores y expresiones.
Por ejemplo, para generar la interface de servicio, definimos el siguiente template (resumido):

public interface ${upperEntityName}Services {
static final ${upperEntityName}Services INSTANCE = new ${upperEntityName}ServicesImpl();

${upperEntityName} buscarByID(Long id);
void eliminar(Long id);
void ingresar(${upperEntityName} ${lowerEntityName});
void modificar(${upperEntityName} ${lowerEntityName});
List buscarTodos();
}

Lo que está dentro de ${} son expresiones, Velocity maneja un contexto en el que podemos insertar objetos con un nombre asociado, en el ejemplo sería upperEntityName y lowerEntityName.

Para invocar al generador usé ANT, la tarea solicita al usuario el nombre de la clase de dominio con su paquete incluido y a partir de la misma usa los templates de Velocity para crear todos los archivos en los directorios correspondientes.

Hemos llegado a automatizar un 95% del desarrollo de los ABMs, siempre tratando de que el generador deduzca la mayor cantidad de cosas posibles a partir del modelo de dominio. Por ejemplo si la entidad define un atributo de tipo Date, es casi seguro que en la JSP de ingreso necesitaremos una caja de texto con un calendario javascript a la derecha y una validación por fecha.

El proceso de desarrollo "copy, paste & replace" se puede optimizar y si invertimos esfuerzo en automatizarlo, no hay dudas que se gana mucho en productividad.

Hasta el próximo post!!

No hay comentarios: