miércoles, 17 de octubre de 2012

Java y el UML maldito

En la entrada de hace unas semanas, En busca del UML perdido, contaba cómo apareció el diseño orientado a objetos, por qué es bueno, y por qué el UML abrió un camino importante para su popularización. Y dejaba en el aire que aunque la programación orientada a objetos sí había triunfado con los años, sin embargo el diseño orientado a objetos no lo había hecho... ¿por qué?.

Voy a centrarme en Java, porque al fin y al cabo en general ha sido el lenguaje dominante durante estos años (lo de que además haya sido el lenguaje que he estado usando yo durante este tiempo es una casualidad nimia y sin importancia, claro).

Los profesores de Ingeniería del Software nos decían (y supongo que nos seguirán diciendo) que el lenguaje final en el que se fuera a programar no importaba, que el diseño se tenía que abstraer de eso y ser genérico, y que luego ya se preocuparía otro de programar en el lenguaje de programación que fuera lo que se había diseñado.

Así, las primeras herramientas UML que aparecieron, entre las que destacaba el Rational Rose (que para eso se había gastado Rational el dinero en fomentar la creación de UML), eran herramientas orientadas fundamentalmente a la documentación. Es decir, el producto que se obtenía al usarlas era un documento, que era el resultado del proceso de diseño, y que se entregaría al programador para que lo siguiera como guía al programar.

¿Qué pasó?. Pues que eso de que el lenguaje final no importe es la primera gran mentira del diseño. Vale, es verdad que eso es posible, pero sencillamente no es práctico.

Para empezar, si tenemos ya un diseño de clases, nos conviene que la herramienta sea capaz de generarnos el código Java a partir del diseño, porque eso nos va a quitar un montón de trabajo absurdo y aburrido. Así surgió la generación de código. Tanto el Rational Rose como otros productos por el estilo que había entonces, como el Paradigm, empezaron a implantar la generación de código en C++... y por supuesto también en Java.


Pero no bastaba con eso. Hay otro problema importante, que se presenta porque como ya comenté el planteamiento del modelo en cascada no suele ser realista. Lo recordamos: el analista Calculín hace el diseño en UML sin pensar en cómo se va a programar, y luego el programador-fontanero Mario (Bros., of course) lo tiene que convertir en Java y preocuparse porque todo eso funcione. Al final Mario Bros. acaba modificando cosas sobre el diseño inicial, porque según se va profundizando en el desarrollo de la aplicación, se van aprendiendo más cosas sobre ella, cosas que pueden afectar mucho al diseño. ¿Qué pasa entonces con ese diseño?. ¿Se tiene que modificar también, según cambiamos cosas en el programa?. ¿Vamos a hacer trabajo doble?. Qué coñazo, ¿no?.

Las herramientas entonces empezaron a implantar otra funcionalidad interesante. Como somos capaces de generar Java a partir de UML, si luego algo cambia en Java... hagamos una función que modifique automáticamente el diseño UML a partir de las modificaciones hechas en Java. A eso le llamaron con el bonito nombre de ingeniería inversa ("reverse engineering").

Todo esto de diseñar en UML - generar Java - modificar Java - volver a UML - volver a Java, etc. al final era, la verdad, un auténtico cacao. Cacao incrementado además porque cada cosa se hacía en una herramienta distinta. A algún comercial de mente despierta se le ocurrió arreglar el problema, ¡cómo no!... poniéndole un nombre chulo al tema (una de las grandes soluciones en todo manual del buen comercial). Así surgio, ¡ta-chán!, la... ¡¡¡round-trip engineering!!! (nuestro traductor a español dimitió el mismo día en el que le dijeron que tenía que traducir algo así y lo único que se le ocurrió fue llamarlo "ingeniería de rosquilla"). Si alguna vez, querido lector, has intentado trabajar en la sincronización bidireccional de dos sistemas que se pueden actualizar por separado, sin duda sabrás que la palabra que mejor puede definir eso es que es un infierno. Se le puede añadir algún calificativo, como el típico "fucking" si hablamos en inglés, o cualquiera de los múltiples equivalentes que existen en el rico castellano, pero vamos, creo que se entiende el tema. Es realmente complicado saber qué lado se modificó antes, qué lado manda, asegurarte de que al generar hacia un lado no se pierde nada que ya teníamos hecho, etc. Es complicado de programar, pero también es complicado de mantener y complicado de entender.

En ese momento, a alguien se le enciende una bombilla en la cabeza... y si nos dejamos de complicar la vida, y más importante aún, dejamos de complicársela al pobre programador... ¿¿¿y si hacemos que haya un sólo modelo???. O sea, ¿y si hacemos que el modelo UML esté representado con el propio código Java?. Creas una clase en Java, la tienes en UML. Modificas algo en un lado, lo tienes en el otro sin tener que hacer nada. Creas una clase en UML, la tienes en Java. No tienes que ejecutar una ingeniería directa ni una ingeniería inversa. Más importante aún, no tienes que ejecutar una "rosquilla" de esas chungas. Sobre todo, eliminamos de un plumazo todas las dificultades que conlleva una sincronización bidireccional. Lo que vemos en UML es lo mismo que vemos en Java. Modificamos cada vez lo que nos sea más cómodo en ese momento. Así surgió una herramienta llamada Together.

Together era una gran herramienta de desarrollo. Podías editar Java a la vez que editabas UML. No se consideraba que el diseño era una cosa distinta a lo que se programaba, se consideraba que el diseño era una vista distinta del mismo modelo. Los ficheros Java contenían el modelo de clases UML completo. Cuando hacías un diagrama, el diagrama se guardaba en un fichero aparte, pero sólo se guardaba el diseño del diagrama, es decir, el modelo final era el modelo Java.


Si sabes un poco de UML y de Java te puedes dar cuenta de cuál es el problema principal. El modelo de clases de UML y el de Java son diferentes. Hay elementos que son idénticos en ambos casos, como puedan ser las clases, pero hay otros cuya correspondencia no es tan sencilla. Por ejemplo, asociaciones, composiciones, relaciones 1-N... Para esos casos, hay que definir un mapeo entre Java y UML. Pero ese mapeo es posible. Aún con eso, sigue habiendo información que nos puede resultar interesante en el diseño UML pero que en Java se pierda. Para eso Java tiene uno de esos elementos geniales que a alguien un día se le ocurrió crear aunque no dejen de ser un parche: las annotations (anotaciones). Vale, estamos hablando de finales de los 90, aún no existían las anotaciones, pero sí que existían en la forma de "comentarios Javadoc". Al fin y al cabo eran lo mismo. Pero en TogetherSoft, los creadores de la herramienta, también tenían sus comerciales molones, y rápidamente le pusieron un nombre a todo esto: le llamaron tecnología "LiveSource".

¿Por qué Together no llegó a triunfar si era una herramienta tan buena?. Lo primero de todo, como IDE no llegaba a ser tan bueno como un IDE de Java de los que existían entonces. En aquella época el IDE que triunfaba era sobre todo el Borland JBuilder, creado en el 95 y que estaba realmente bien. Eso era un peso importante, porque si tienes que elegir entre un "gran" IDE Java y un "buen" IDE Java que-además-tiene-UML, la decisión no es tan fácil. Además, en mi opinión había algunos problemas con el mapeo Java-UML, que al fin y al cabo es el problema fundamental. Algunas decisiones me parecían bastante discutibles.

Sin embargo, no creo que ninguno de ellos fuera el mayor problema. El mayor problema que se encontró Together fue puramente comercial. Por un lado, TogetherSoft no era una marca con peso suficiente como para hacer grandes campañas comerciales, no llegó a hacerse tan popular como llegó a ser el Rational Rose. Por otro, y más importante... Together nació en 1999 (o 1998, no estoy seguro)... y con el paso de los años hemos visto cómo surgió Netbeans primero (en 1999), y Eclipse después (la versión 1.0 es del 2001), y que al final fue el que se llevó el gato al agua y se convirtió en el IDE Java más usado. Ambas triunfaron no por ser mejores que JBuilder, sino porque mientras que esta era de pago, las otras dos eran -y siguen siendo- gratuitas. Ahora mismo, el modelo de sacar un producto gratuito para que domine el mercado y acabar teniendo ganancias por dar soporte a empresas y cursos se sabe que puede funcionar (siempre que el producto sea realmente bueno), pero por aquel entonces era difícil ver a compañías de desarrollo que apostaran por él. El caso es que Together era de pago. Es más, por lo que recuerdo era aparentemente cara, de esas que no dicen su precio en la web (sí, siempre usé una versión pirata...). ¿Por qué iba nadie a pagar por esa herramienta existiendo IDEs que son mejores para el desarrollo Java y que además son gratis?.

Rational Rose había llegado a tener cierta popularidad, es más, muchas empresas compraron licencias del producto, pero en el fondo no dejaba de ser un producto fallido desde el momento en el que se separaba el diseño del código. Era un gran producto académico, no tan bueno para el mundo real. Y costaba una pasta. Las nuevas versiones se centraban más en que hiciera cada vez más cosas, más que en que lo que hiciera lo hiciera bien y fuera práctico. La gente se cansó de él, y sólo las empresas que tenían que justificar la producción de un documento de diseño siguieron utilizándolo... y cada vez menos, pasándose en muchas ocasiones a herramientas con las que dibujar cajitas y diagramas, como Visio, Flowchart o sobre todo los mismísimos Word o Powerpoint. Together era un gran producto, pero nunca llegó a ser popular. Demasiado ambicioso en el momento equivocado. Como curiosidad, puedo añadir que Rational acabó siendo comprada por IBM (autores de Eclipse), y Together acabó siendo comprada por Borland (los del JBuilder, y la mejor empresa para desarrolladores hasta ese momento... a esa la mató el software libre, claro). Ambos productos siguen existiendo, pero... ¿conocéis a alguien que los use?.

Pasaron los años y el UML languideció. La cascada y un puñado de dólares lo sepultaron.

¿Qué hubiera pasado si el comercial de TogetherSoft en lugar de perder el tiempo pensando en nombres molones para su tecnología, hubiera ofrecido el producto gratis?. Estoy convencido de que la historia hubiera sido distinta, y ese tipo estaría ahora tumbado en una hamaca hecha de billetes de dólar (bueno, igual está así de todas formas, a saber). La herramienta seguramente habría seguido creciendo, pero en lugar de buscar motivos comerciales, habría buscado funcionar cada vez mejor. Como le pasó a Eclipse especialmente los primeros años. Y ahora UML estaría posiblemente en un trono. O no... (pero yo pienso que sí!).

Se puede decir que en los 2000, sin haber acabado nunca de despegar, UML se fue difuminando cada vez más. Se necesitaban nuevas herramientas. Comenzaron a aparecer "plugins" de UML para Netbeans y/o Eclipse, la mayor parte de ellos siguiendo el modelo de Rational, es decir: orientado a la documentación, y de pago. También surgió alguna herramienta de UML gratuita, como ArgoUML, pero por un lado en general seguían estando orientadas a la documentación, y por otro el acabado normalmente no era suficiente como para convencer a nadie para que las usara.

En el año 2002 (o quizá 2001), aparece un plugin para Eclipse llamado "EclipseUML" y creado por una empresa llamada Omondo. Las intenciones de Omondo eran muy buenas, el plugin es gratuito y siguen la filosofía "LiveSource" de Together, es decir, el modelo UML se guarda en las propias clases Java. Omondo rebautizó esta técnica como "live round-trip". Las primeras versiones no tenían tanta funcionalidad como tenía el Together, pero al estar integradas con Eclipse, el IDE de Java seguía siendo el mejor. Y lo cierto es que el editor de UML no estaba mal y cumplía muy bien con lo mínimo que se le podía pedir. ¿Esperanza?.

Pero todo se fue al traste en cuanto alguien se dio cuenta de que eso que estaban haciendo ellos, hasta ese momento se estaba cobrando. El dólar volvió a aparecer. Así, el producto empezó a ofrecer una versión gratuita y otra de pago. Una de las "pequeñas" diferencias entre ellas era... que la versión gratuita no se podía usar en proyectos que estuvieran bajo control de versiones, es decir, CVS, Subversion, etc... espera... ¿¿¿pero qué proyecto medianamente serio no está en control de versiones???. Si esto ya de por sí es casi casi volver a caer en los mismos errores del pasado (hay una ventaja importante, y es que seguimos dentro de Eclipse), de repente a los señores de Omondo se les ocurre que por si acaso eso no es suficiente para hundir del todo el producto, mejor darle un empujoncito. Así, en un momento dado por cada versión nueva del plugin que sacaban, cambiaban el formato de los ficheros de diagramas. Es decir, si cambiabas la versión del plugin, tenías que volver a dibujar todos los diagramas. Como además la versión del plugin estaba ligada a la versión de Eclipse, si querías actualizar Eclipse tenías que actualizar el plugin. Ni sé, ni quiero saber, qué habrá sido del plugin de Omondo. Sólo sé que cuando he visto alguna vez su página me ha parecido que volvían a haber cada vez más y más funcionalidades "avanzadas". ¿Repitiendo más errores del pasado?.



También ha habido alguna aproximación diferente, limitada pero interesante. Por ejemplo UMLGraph, que propone algo radicalmente distinto: en lugar de dibujar nosotros los diagramas, esta herramienta los generará automáticamente y los meterá dentro del JavaDoc. El modelo por tanto es también el modelo Java, usando también anotaciones para enriquecer la información UML. Esta aproximación me parece muy interesante como herramienta complementaria, pero no tanto como herramienta única.

Han aparecido también otros plugins gratuitos con la idea del LiveSource, como por ejemplo Green UML, pero el problema de este plugin es... el que dice el nombre, que está verde cual aceituna bañada en rayos gamma (aunque confiamos en que florezca y se convierta en una linda mariposilla). Otros plugins son gratuitos pero siguen con la idea del diseño como documento y la mandanga del roundtrip, como Papyrus ó el propio plugin oficial de Eclipse MDT / UML2.

Es frustrante, porque teniendo en cuenta la arquitectura modular de Eclipse y que tiene módulos para tanto para hacer fácilmente diagramas como para manejar el código fuente de Java a cualquier nivel, lo cierto es que hoy por hoy sería fácil hacer un editor de UML con LiveSource. Ahí tenemos el ejemplo del Green UML, ¡que surgió como un proyecto hecho por estudiantes en la Universidad! (no tengo claro si fue para un proyecto de fin de carrera o para una tesis, pero imagino que fue para algo así).

¿Está todo perdido?. ¿Caemos una y otra vez en los mismos errores?. ¿Qué es lo mínimo que debería tener una herramienta UML para que sea práctica al trabajar en proyectos Java?. ¿No existe ninguna ahora mismo que apunte a eso, todo son fracasos?. ¡Quiero usar una!. ¿Andrés, eres tan abuelo cebolleta que no eres capaz más que de hablar del pasado?. La respuesta a todas estas cuestiones, en la tercera parte de esta serie sobre UML, que como no podía ser de otra forma se llamará "UML y la última cruzada". En pocas semanas en este humilde blog.

6 comentarios:

  1. Me ha gustado la descripción tan visual que haces de Green UML :-)
    ¡Buen artículo!

    ResponderEliminar
    Respuestas
    1. Gracias! Sí, la verdad es que el nombre le viene que ni al pelo. Es una pena, si le dieran un empujoncito podrían tener algo bastante chulo

      Eliminar
  2. Entonces, se puede decir que no hay ninguna herramienta decente que sirva?

    ResponderEliminar
    Respuestas
    1. Respuesta rápida: no, lamentablemente no la hay :-(
      Respuesta más razonada... tengo pendiente escribir la continuación del artículo, donde hablaré de ObjectAid, que para mi es insuficiente pero ahora mismo seguramente sea la mejor opción (que yo conozca)

      Eliminar
  3. Nice post. You may be interested by the UML online modeler called GenMyModel. It designs UML-compliant models in a web-browser and generates code. http://www.genmymodel.com

    ResponderEliminar
    Respuestas
    1. Thanks, the tool has a great look! It has only a problem for me: I don't believe in the separation between UML design and coding, I rather see them as different views of one same thing. So, for me live source / live round trip is a must. I guess it'd be difficult for GenMyModel to achieve that, because it'd require to be integrated with a Java IDE... maybe Eclipse Orion in a future?

      Eliminar

cookie consent