lunes, 31 de diciembre de 2012

Para el 2013, no lo dudes... ¡Apaga y vuelve a encender!

Llega un nuevo año y quien más quien menos, casi todos caemos en la tentación de hacer un repaso mental del año y hacer nuestros propósitos para el siguiente. Que luego llevemos a cabo alguno de esos propósitos es harina de otro costal, claro...

Por mi parte no tengo grandes propósitos, nunca he sido muy amigo de hacerlos. En cuanto a mis inquietudes informáticas, intentar aprender algo de Android, llevar a cabo algún proyecto de los que tengo en mente o a medias (que los tengo, seguro que alguno acabo haciéndolo), mirar mejor alguna de las tecnologías que están saliendo en cuanto a desarrollo web puro, como LESS-SASS ó Bootstrap, quizá mirar un poco Scala y otros lenguajes funcionales que ahora parece que se están poniendo de moda, quizá algo de BDD... ¡yo qué sé!. Sobre todo, seguir con este blog, en el que hable de lo que he dicho antes unido a otros intereses como buenas prácticas de software y mi gran pasión en esto del desarrollo, que hasta ahora no estoy sacando mucho, la reutilización.

Para los demás, desde este blog tengo un mensaje ineludible. Si estás triste, desprecias a los políticos del mundo (bueno, eso lo hacemos todos), la crisis te tiene agobiado o peor aún, estás en paro y no te sientes útil, o si no consigues que te salga nada de lo que intentas, o si estás harto de la saga Crepúsculo, o si sientes que este mundo no es para ti... en definitiva, si tu vida no es tal como te gustaría y el rumbo no parece muy claro, la solución universal a todos los males del mundo está clara, atrévete... ¡¡¡apaga y vuelve a encender!!!.

Verás lo saludable que puede resultar.



¡¡¡FELIZ 2013 A TODOS!!!

jueves, 29 de noviembre de 2012

Maven. Te quiero. Te odio

Querida... amada Maven:

Ya sabes que nuestra relación ha sido siempre muy complicada. Hemos tenido que pasar por mil y una dificultades, hemos tenido que sortear cientos de obstáculos y aunque siempre parecía que lo nuestro no funcionaba, una y otra vez conseguíamos encontrar esa solución mágica que nos hacía superarlo.

En cuanto te conocí me di cuenta al instante de que recogías muchas de las virtudes que llevaba tanto tiempo buscando. Me volvía loco tu repositorio y tu gestión de las dependencias, con ese toque de transitividad que sabías darle, como nadie había sabido hacer hasta ese momento. Y eso a pesar de que la inseguridad que conlleva la primera vez te llevaba a menudo a no dejar claras tus prioridades. Pasaron años hasta que fuiste capaz de organizarte para que no quedara nunca la duda sobre qué versión elegir. Sólo esto ya era suficiente para estar contigo. Todavía hoy no he visto nunca otra que te haga sombra en esto, como mucho algunas lo que hacen es copiarte sin siquiera querer ocultarlo. No sólo eso, desde el principio me aportaste algo más que necesitaba mucho en ese momento, como es la posibilidad de orquestar varios proyectos y tener una gestión clara de la creación y gestión de sus versiones. Y también facilitabas e integrabas muy bien la ejecución de las pruebas unitarias.

No todo fue bonito, ni mucho menos. Siempre te gustó jugar conmigo, siempre te gustó ponérmelo difícil. Cada vez que se me ocurría proponer algún plan que se saliera de a lo que estabas acostumbrada en cuanto a la construcción de los paquetes y componentes, tú te ponías nerviosa y colocabas barreras para que conseguirlo fuera un suplicio. Algo que parecía muy sencillo se convertía en complicado, y a menudo tenía que buscar cómo engañarte para que te acabara gustando lo que te proponía.

A esto contribuía mucho la falta de comunicación que teníamos. Nunca me decías cómo te sentías realmente, te ponías misteriosa y no me ayudabas a sacar las cosas adelante. Muchas veces me contabas verdades a medias sobre tus plugins, o me dabas información anticuada que había cambiado lo suficiente como para que ya no me valiera, y a menudo tenía que explorar en lo más profundo de tu ser, llegando hasta el mismísimo código fuente, para descubrir lo que te ocurría realmente.

Parte de la culpa de todo esto la tiene seguramente mi ex-novia, Ant, que no tenía ninguna de tus mejores virtudes pero que si brillaba en algo era precisamente en la construcción personalizada de los componentes. Tú siempre has valorado más la construcción estandarizada, y no te lo reprocho, pero no creo que lo uno tenga por qué interferir con lo otro. De hecho mi ex, corroida por la envidia, te intentó copiar y se compró un coche llamado Ivy para competir contigo en la parte más básica, la gestión de dependencias. Mi ex tiene su público, claro, pero cuanto más tiempo ha pasado más me he dado cuenta de lo anticuada que es en realidad. Ahora veo que estandarizar la construcción tiene bastantes ventajas.

En cualquier caso, seguramente lo peor por lo que he tenido que pasar en nuestra relación es que te integrabas muy mal con mis amigos del club Eclipse. No te querías ni acercar por allí, y me obligabas a hacer malabarismos para que no chocarais en vuestros planes. A veces coincidíais tangencialmente y teníais algún tipo de contacto, lo suficiente para aprovechar sobre todo tus maravillosas dependencias, pero el contacto nunca llegaba a ser realmente amistoso.

Con el tiempo mi paciencia fue dando frutos, y gracias a eso te fui descubriendo nuevas sorpresas. Ese repositorio Nexus que mejoraba el rendimiento y hacía de repositorio central corporativo, esos arquetipos que hacían que no tuviéramos que empezar siempre desde el principio, esa integración con herramientas como OneJar y Launch4j que comentaba en mi artículo de hace varias semanas... y sobre todo fue un gran descubrimiento el día que se unió a nosotros nuestro fiel perro, Jenkins. Gracias a él muchas de tus incomodidades se gestionaban mejor, y perdía mucho menos tiempo con todos esos deploys que tenía que hacer tan a menudo. Debo decir que él y tú sí que encajabais perfectamente y parecíais hechos el uno para el otro.

Pero... no quiero salirme del tema. Te escribo esta carta porque me siento engañado.

La otra noche pasé por el nuevo local del club Eclipse en la calle Juno. La verdad es que llevaba mucho tiempo sin conocer ninguno de los locales que habían ido abriendo por la ciudad, quizá con miedo de que tu falta de integración se acrecentara en ellos.

Y cual fue mi sorpresa cuando... te vi allí, en el club. Alternando con todos, como una ramera barata. Dejando que cualquiera te tocara el culo sin poner ningún tipo de oposición. Hablando con todos, ayudando a todos. Con todos, hasta con el más tonto de los dummies. Cualquiera era capaz de manejarte, de entenderte, así de fáciles les ponías las cosas. De repente, dejaste de lado todas esas dificultades que me habías puesto a mi. Hacías que usarte fuera lo más fácil del mundo, que prácticamente no hiciera falta saber nada. Que con dos clicks tuvieras creado tu proyecto y que con otro más añadieras las dependencias que necesitaras. Por supuesto, sé que debes seguir teniendo complejidades escondidas, que irían apareciendo con el tiempo. Pero llegar a ti es ahora mucho más fácil.

Sé que no te diste cuenta, que me confundiste con cualquier otro de los múltiples acompañantes que tuviste, pero esa noche... esa noche yo también te usé. No pude evitarlo. Ya no soy importante para ti... debería matarte, o al menos abandonarte para no volver a verte jamás. Los celos me carcomen, no puedo soportarlos. Pero ya no puedo vivir sin ti. Es mucho lo que me das.

A partir de ahora seré uno más en tu vida, otro usuario anónimo que entra y sale pasando desapercibido. Pero quiero que sepas que nuestra historia fue muy especial durante mucho tiempo y que no te olvidaré jamás. No es una carta de despedida, pero sí que es la última vez que te hablaré como alguien especial y cercano a ti.

Te quiero. Te odio.


P.D.: Tengo una nueva vecinita llamada Gradle que me está intentando seducir. Sabe qué teclas tocar, ya que afirma que reúne tus ventajas con las de mi ex. Por ahora me resisto, he sufrido demasiado y no me siento con fuerzas para empezar otra vez, pero como un día me dé por conocerla mejor igual te acabas olvidando de mi para siempre...



miércoles, 14 de noviembre de 2012

Metodologías ágiles. ¿Me las creo o no me las creo?

Últimamente parece que los congresos y otros saraos sobre metodologías ágiles de desarrollo aparecen de debajo de las piedras. Están de moda, está claro. Ante todo, debo reconocer que aunque realmente me encantaría haber podido hacerlo, hasta ahora no he participado nunca en un proyecto en el que se siga alguna metodología ágil. Así que en este artículo parto del desconocimiento y diré irremediablemente un montón de tonterías. En cualquier caso, ya adelanto que las metodologías ágiles me generan tanto entusiasmo como dudas.

En el año 2001, Kent Beck (que básicamente quería vender su libro) convocó a unas cuantas mentes pensantes del desarrollo software y, con una cerveza en la mano, les dijo algo así como: "Señores, ¿están tan hartos como yo de tanta tontería?". El resto se miraron unos a otros, pensando cada uno en ese sufrimiento que les acarreaba el día a día en el trabajo: la incomprensión de sus jefes, ese documento que no vale para nada y nunca se acaba, el echarse las culpas unos a otros... Así que cogieron la petaca de whisky, la apuraron de un trago y todos al unísono gritaron: "¡¡¡Cambiemos el mundo!!!". Vale, seguramente no fue exactamente de esta forma, pero ey, si yo fuera a hacer una película sobre el tema la haría así, ¿qué pasa?.

El caso es que dice la leyenda que estos 17 tipos se pusieron de acuerdo para redactar los 4 principios maestros del desarrollo ágil, recogidos en lo que vinieron a llamar el manifiesto ágil (por cierto, cualquiera que haya estado en una reunión de su comunidad de vecinos sabrá que el que 17 tipos se pongan de acuerdo en algo en una tarde es cuanto menos difícil de creer, pero atribuyamos el mérito al alcohol y créamoslo, que al fin y al cabo da un poco igual si sucedió así o no). Los 4 principios tienen la forma "X mola más que Y", que no es que Y no mole, que si hay que ir se va, pero es que X es la leche y es lo que hay que potenciar. Estos son los 4 principios o valores.

1. Viva la gente (la hay donde quiera que vas)



Como comentaba en mi primer artículo sobre UML, unos años atrás las mentes pensantes del desarrollo de software se estrujaban las meninges buscando una metodología que hiciera el desarrollo tan fácil que cualquier mequetrefe fuera capaz de hacerlo con los ojos cerrados. Se pretendía que el desarrollo no fuera un proceso creativo, sino que siguiendo unos pasos bien definidos se pudiera casi automatizar.

Pero esto no es cierto. Lo cierto es que para hacer un buen diseño, que sea flexible y mantenible, tienes que ser creativo. Tienes que pensar. Y está demostrado que un buen desarrollador cunde más a largo plazo que muchos malos.

Por otra parte, también está demostrado que el rendimiento de una persona que está motivada con lo que hace es infinitamente superior al de la que no lo está. Esto tiene muchas implicaciones. No es fácil estar motivado. Tienes que sentir que controlas completamente el software que estás haciendo, que lo conoces bien, que tienes tu parte de responsabilidad sobre él. Tienes que hacer tareas creativas, no tareas aburridas.

Y aquí llega mi primera duda. Porque la vida real... ¿es así?. ¿No aparecen día sí y día también tareas soporíferamente aburridas, que no se pueden atajar haciendo de otra forma y que además no hay más remedio que hacerlas?. ¿No hay un montón de gente que se ha metido en el desarrollo porque da de comer, pero que realmente ni se sienten especialmente motivados ni les interesa sentirse así, sino que se prefieren limitarse a "cumplir órdenes"?. ¿Dónde encaja todo esto en las metodologías ágiles?.

2. Muerte al papel (efecto Fahrenheit 451)



Tradicionalmente creo que ha habido dos grandes problemas con la documentación. El primero es que muchas metodologías "de las antiguas" requerían una cantidad indecente de documentación. Yo personalmente he trabajado en proyectos en los que el equipo que había se tiraba más de un año haciendo toneladas de documentación, y cuando se querían dar cuenta no habían hecho nada de software real y el tiempo se estaba acabando. Al final resulta que se tiene que hacer todo el desarrollo corriendo y sin que la mayor parte de la documentación existente ayudase demasiado. Es una pérdida de tiempo y de energías, y además, desmotiva.

Pero el segundo problema creo que es aún peor, y tiene que ver con el paso del tiempo. Ocurre porque el software y la documentación son entidades diferentes. Están disociadas. Llega un momento en que, una vez entregada la primera fase del proyecto, dentro del mantenimiento se modifica el software pero no la documentación. ¿Para qué sirve una documentación que no está actualizada?.

Para resolver esto, en mi opinión lo que hay que hacer es integrar la documentación en el propio software. Olvidar la idea del "documento". Un gran ejemplo de esto es el JavaDoc. Pero creo que no basta con eso. Creo que aún nos falta subir más de nivel de abstracción. En mi segundo artículo sobre UML ya mencionaba la importancia de que los diagramas UML estuvieran integrados con el código Java, usando lo que se llamó (entre otros nombres) "live round-trip". Y aún podría ir más allá, porque también tengo mis propias ideas sobre el análisis de requisitos integrado con el código. Pero eso ya lo contaré en otra ocasión (me queda mucho de lo que hablar hasta llegar ahí)...

En este punto de la documentación, la verdad es que mis dudas son menores. Lo único que me pregunto es: ¿la gente estará siendo capaz de medir bien y ser racional con la documentación que se produce para el software?. En esto de la documentación, yo casi siempre lo que he visto han sido extremos: o te obligan a documentar demasiado, o no se documenta nada. Es decir, ¿se estará usando esto como excusa para no documentar nada de nada?. ¿Ni unos mínimos JavaDoc, ni una mínima documentación de intenciones, nada de nada?.

3. El cliente es tu amigo



Tengo que reconocer que la idea es muy buena. Es difícil que el software que se produzca satisfaga al cliente y cumpla sus necesidades cuando el cliente no está ahí siempre que haya alguna duda. Si hay que esperar a que haya una reunión para preguntarle, todo se retrasa. Muchas veces se tira "por el camino del medio", acertando en algunas ocasiones y en otras no. Muchas veces esas reuniones, cuando por fin llegan, se estiran y estiran y cuando sales te das cuenta de que no le has preguntado nada de lo que necesitabas saber (y que te duele la cabeza, además). Pero también muchas, muchas veces, el cliente se para a mirar lo que llevas hecho cuando sólo quedan dos semanas para la puesta en producción. Y entonces decide cambiarlo todo.

La idea, como digo, es buenísima, que el cliente participe dentro del propio desarrollo, que haya una comunicación frecuente con él y pueda resolver todas las dudas rápidamente. Pero... ¿es realista en la mayor parte de las ocasiones?. ¿De verdad los clientes se prestan a colaborar en los proyectos?. En mi experiencia, muchos clientes tienen su propio trabajo que sacar adelante, y consideran que no tienen tiempo para eso. Consideran que es tu problema. No entienden la importancia de ese tema. Ya te han contado qué es lo que necesitan, así que déjales en paz. Por supuesto, hay clientes y clientes. Pero me surgen muchas dudas sobre la resistencia que presentarán muchos clientes en contra de esa colaboración.

4. Be water, my friend



Ya he comentado en alguna ocasión que el desarrollo de un producto de software es un proceso de aprendizaje. Según se va profundizando en él, mejor se va entendiendo, y al hacerlo se van descubriendo nuevas implicaciones del desarrollo. Cosas nuevas que hay que hacer, o cosas que cuestan mucho más de lo que se había pensado al principio porque obligan a cambiar otras cosas o no se pueden plantear como se tenía previsto. Esto hace que los planes a largo plazo (e incluso a medio, y diría que muchas veces hasta a corto) sean difíciles de seguir, porque lo normal es que se descubran cosas nuevas sobre la marcha, y en ese caso siempre hay que acabar sacrificando algo. O el proyecto sale menos rentable, o se resiente la calidad del producto, o (más a menudo de lo que debería, sobre todo en consultoras) lo que se sacrifica es el tiempo de los programadores, que acaban haciendo horas no retribuidas como campeones, apelando al "compromiso con la empresa".

En cualquiera de los casos, se propaga un sentimiento de culpabilidad: "alguien ha hecho algo mal". "Esto no debe seguir así". "A partir de ahora vamos a hacer las cosas bien, y vamos a... planificar más cosas y mejor".

Las metodologías ágiles afrontan este problema dándole más importancia a la "respuesta al cambio" que al plan. Esto tiene una implicación enorme sobre la forma de trabajar de las empresas con sus clientes: requiere cambiar la forma en la que se hacen los contratos con el cliente. Ya no valen contratos cerrados, tipo "me haces todas estas funcionalidades en este tiempo y yo te pago esto". Nos vamos a una facturación por tiempo trabajado. Por un lado eso invalida directamente este tipo de desarrollos con determinado tipo de contrataciones, por ejemplo, cualquier proyecto con la administración pública, que tiene que ser cerrado por definición. Aparte de eso, ¿cuál es el problema de esto?. Que requiere una gran confianza. Confianza del cliente hacia la empresa del desarrollo, para que no piense "estos me están queriendo timar, me están cobrando una barbaridad para lo que están haciendo". Confianza del gestor de la empresa de desarrollo con el equipo que va a programarlo, para que no piense "estos se están pasando el día tocándose las narices, y el cliente se va a cabrear y nos va a dejar tirados".


¿Y en el fondo, no es ese el principal problema que tienen las metodologías ágiles? (aparte del hecho de que hay un conjunto grande de gente y/o situaciones para las que sencillamente no valen). Que requieren confianza. Que requieren querer hacerlo. Confianza del programador en el resto del equipo, confianza en que se está haciendo lo correcto, confianza en que la dirección lo va a soportar, confianza en que el cliente lo va a apoyar. Confianza de la dirección en el equipo de desarrollo, confianza en que va a funcionar bien, confianza en que al cliente le va a gustar. En definitiva, requieren que todos los implicados crean en lo que se está haciendo, desde el cliente que pone el dinero hasta el becario que echa una mano con lo que sea. Requieren que todos crean en el trabajo de ese equipo y de todos y cada uno de sus componentes.

¿Y sabéis qué?. Que yo me creo todo eso. Creo en la sinergia. Creo en que cada persona es capaz finalmente de asumir responsabilidades por sí misma, cuando se le otorga la confianza para que lo haga.

Pero no estoy seguro de que el mundo esté preparado para ello. Me parece un cambio de orientación demasiado grande y que afecta a demasiadas partes. Tengo muchas dudas. Me cuesta creer que las metodologías ágiles se estén usando de forma generalizada.

Así que si estás leyendo esto y has tenido ocasión de trabajar en algún proyecto siguiendo una metodología ágil, por favor, deja un comentario y comparte tu experiencia. Cuéntanos cómo convenciste a tus clientes y a tus jefes. Yo estoy dispuesto a apurar mi petaca de whisky y gritar: "¡Cambiemos el mundo!".


NOTA: Sí, los chistecillos son míos, haciendo un poco el tonto con el Inkscape juntando personajes que he cogido de por aquí y por allá (he procurado que fueran todos de dominio público). La mayor parte proceden de Open ClipArt.

martes, 30 de octubre de 2012

Breezi: la herramienta con la que tu abuela podrá crear la web de su club de ganchillo


Puede parecer que esto de los creadores WYSIWYG (o sea, editores visuales) de HTML no es nada nuevo. El Dreamweaver es quizá el editor de webs que llegó a ser más popular, de hecho hace unos años era una de las herramientas más pirateadas por los desarrolladores. Lo cierto es que con el Dreamweaver podías más o menos hacer webs aunque no tuvieras ni idea, pero llegaba un momento en que no era tan fácil. Ese momento en el que sentías que la herramienta no te dejaba hacer lo que querías, todo se embarullaba y perdías por completo el control sobre tu creación. Las tablas dentro de tablas dentro de tablas dentro de tablas no había nadie que las manejara ya, de repente tenían vida propia. Ya no podías cambiar lo que habías hecho, ya no estabas pensando en cómo quedaba mejor la web. Ya no sabías por qué salía ese hueco ahí ni qué podías hacer para quitarlo. Eso se había convertido en una guerra contra la herramienta. Sólo puede quedar uno.

En cualquier caso, lo que acabó matando a Dreamweaver del todo (aunque la herramienta sigue existiendo, pero su popularidad ya no tiene comparación con la que tuvo) fue el declive del diseño de layouts con tablas y la popularización del diseño basado en CSS. Hacer un diseñador de layouts basados en CSS que resulte intuitivo es mucho más complejo, e incluso muchos podrían pensar que es imposible hacer uno que no requiera de ningún tipo de conocimiento de HTML y CSS.

En este contexto, aparece Breezi. Y Breezi es... la leche. Así de claro. Hace unos días la estuve probando, y hacía tiempo que no probaba algo que me haya entusiasmado tanto. Todo está tan bien pensado y queda tan natural que parece fácil. Pero no lo es, ni mucho menos.

Para mis pruebas quise hacer algo para lo que no tuviera que ir creando imágenes ni logotipos ni fotos, porque no soy diseñador y como tenga que ponerme yo a hacer dibujillos podía tirarme meses. Además quería basarme a ser posible en un caso real, un rediseño de una web sería genial. Así que mi planteamiento fue... ¿cómo haría yo un rediseño de la web de... mi escuela de baile? (sí, amigos, también bailo, o lo intento, ¿a que soy una caja de sorpresas?). Por cierto, si os gusta el baile, queréis aprender y vivís en Madrid, ya estáis tardando en ir a esta academia, porque es muy buena y no sólo aprendes mucho sino que además te lo pasas a lo grande: escuela de baile Sálsalon. Como podéis ver su web se está quedando un poco antigüilla, así que me pareció perfecta para las pruebas (sé que están trabajando en cambiarla, y digo yo que la harán diseñadores de verdad, no informaticuchos sin gusto estético como yo).

Por lo pronto, Breezi es una aplicación web, que además incluye el hosting. Esto quiere decir que cuando tengas hecha tu web no tienes por qué andar pegándote con servidores FTP ni otras zarandajas. Pulsas el botón de "Publicar" y automáticamente tu web está en Internet, en la dirección "midominio.breezi.com". Si no quieres pagar nada, puedes hacer una web pequeña que esté en esa dirección y que tenga un máximo de 3 páginas, insuficiente en el mayor parte de los casos pero potencialmente suficiente para algunas empresas pequeñas que sólo quieren tener un pequeño escaparate, sin demasiadas necesidades informativas. Si quieres hacer una web completa y que tenga su propia dirección, puedes hacerlo por 150 dólares al año. Teniendo en cuenta que esto incluye el hosting, no me parece ninguna barbaridad. Existe también una modalidad de pago a dólar por cada hora de uso del editor, que puede ser muy interesante si no queremos gastar mucho dinero y queremos apurar (esta modalidad puede dar mucho lugar a la picaresca, así creo que se puede considerar muy española). Pero dejemos a un lado el vil metal y vamos al lío.

En cuanto a los layouts, Breezi permite crearlos usando un diseño basado en cuatro elementos:

  • El primer elemento son los bloques principales, que son contenedores horizontales que vienen ya creados por defecto para facilitar las cosas: cabecera, introducción, cuerpo y pie.
  • Dentro de cada uno de ellos se pueden crear secciones, que vuelven a ser bloques horizontales que se añaden libremente
  • Dentro de cada sección se pueden crear varias columnas, que son bloques verticales. Se pueden ir creando, eliminando y redimensionando sobre la marcha
  • Dentro de cada columna se van apilando de forma vertical los componentes de contenido, que Breezi llama aplicaciones. El nombre me parece un poco engañoso, la verdad, quedaros conque son unidades prediseñadas de contenido. Quizá hubiera quedado más claro si las hubieran llamado widgets.

Todo esto está muy bien, pero evidentemente crear una página desde cero siempre es complicado, y Breezi lo sabe. Así que nada más crear una página, lo primero que te da para elegir son un montón de plantillas prediseñadas, para que puedas partir del layout que se parezca más a lo que tengas en la cabeza e ir modificándolo sobre la marcha. Se agradecen detalles como que estas plantillas vengan en blanco y negro y sin grandes suposiciones sobre el estilo gráfico (aunque también tienen otras que incluyen el diseño, para los más vagos). También se agradece que no sean layouts vacíos, sino que incluyan textos, noticias u otros elementos de contenido que se suelen utilizar en las páginas. Esta es una de las grandes maravillas de Breezi, te da siempre ya prediseñado lo que más se suele utilizar, y luego te permite cambiarlo.

En cuanto a la personalización del estilo cada elemento, uno de los problemas típicos que han tenido siempre los editores gráficos es cómo hacer que el usuario pueda elegir correctamente cuál personalizar. Es decir, si un bloque tiene dentro una sección que tiene dentro una columna que tiene dentro una aplicación, ¿cómo puedo hacer que cada una tenga un botón distinto para personalizarla?. La opción por la que opta me parece inteligente: separar cada botón de personalización de los contenedores adyacentes para que puedan pulsarse por separado: uno aparece en horizontal, otro en vertical, otro en diagonal, otro más separado... Para cada elemento podrás personalizar sus márgenes y espaciados y podrás ponerles bordes, sombreados...


Una vez tenemos nuestro layout más o menos definido (o fusilado directamente de la plantilla), comenzamos a meter contenido. Para eso tenemos las aplicaciones. Una aplicación puede ser desde un menú hasta combinaciones de texto e imágenes, pasando por botones, formularios de contacto, galerías, noticias, conjuntos de iconos sociales... Cada aplicación tiene un botón para configurarla en general, como por ejemplo editar los elementos del menú, o las imágenes que aparecerán en la galería. Además, cada aplicación estará compuesta por varios elementos que se pueden configurar por separado. En el caso de los textos, por supuesto tendremos el inevitable editor con sus fuentes (incluyendo las fuentes de Google, por cierto), negritas, colores, etc. A cada elemento de una aplicación se le puede dar estilo por separado, dependiendo los estilos disponibles del tipo de elemento en cada caso.


Otra de las cosas que más me ha gustado es que los contenidos se adaptan al tamaño de su contenedor. Esto es especialmente chulo en el caso de las imágenes. Cuando añades una imagen, esta calcula el tamaño que tiene disponible y te permite seleccionar qué parte de la imagen es la que quieres mostrar, redimensionándola si es necesario y sin deformarla salvo que le digas explícitamente que la quieres así. Sin apenas darte cuenta, has adaptado la imagen en unos segundos.


En fin, lo más importante que puedo decir es que en todo momento tenía la sensación de que el tiempo lo estaba empleando en jugar con el diseño, no en que el diseño jugara conmigo. Sobre todo, tenía la sensación de que no me estaba pegando con la herramienta, sino que en todo momento Breezi me estaba ayudando a sacar el diseño adelante. El resultado no es precisamente espectacular, porque ya he dicho que no soy diseñador, pero teniendo en cuenta mis grandes limitaciones sí que llegó a sorprenderme. En unas horas, ya tenía hecha una página de inicio casi completa, a pesar de que tuve que ir aprendiendo a usar la herramienta sobre la marcha. Podéis verlo en salsalon.breezi.com (no lo he puesto como enlace a propósito, para evitar que aparezca en los buscadores y engañe a algún incauto).


Cabe añadir también que puedes exportar la web resultante, para que se sincronice con Dropbox o con un FTP. Es decir, puedes publicar la web en otro servidor sin problema alguno, incluso con la opción gratuita. Y que la web resultante funcionará bien en todos los navegadores, y si accedes con un móvil te das cuenta de que sin querer acabas de crear un diseño responsive (que no sé cómo narices se traduce, si es que tiene traducción).

Por supuesto, no es oro todo lo que reluce. Al ejecutarse todo en el navegador y con un porrón de Javascript, se necesita un ordenador con cierta potencia para que vaya fluido. Y consume un montón de memoria. También es obvio que es más limitado que el HTML escrito a mano. Por último, el código que se genera es inevitablemente sucio, aunque no tanto como podría haber sido. Pero creo que todo estas limitaciones son inevitables en un editor WYSIWYG. También debo reconocer que no he probado otras herramientas del mismo tipo, como Weebly, Sidengo ó Wix (aunque si he probado esta es precisamente porque es la que me dio mejor pinta). Por último, esta herramienta apenas tiene unos meses, así que todavía puede mejorar aún más con el tiempo (o estropearse, que ejemplos hay miles).

En resumen, Breezi tiene dos cosas que son alucinantes: una, que es una gran herramienta para hacer un prototipo y ayudarte a pensar en el diseño de tu web, y dos... que gracias a ella hasta tu abuela es capaz de hacer una web chula, y dejar en pañales tu último intento de meterte a diseñador. Mejor no se la enseñes, que corres el riesgo de quedarte sin "cocretas" y lentejas para siempre.


Nota: No recibo comisión (ni jamones) ni de Breezi ni de Sálsalon, ¡de verdad!. Sé que prometí en la columna de la derecha que iba a gruñir mucho, y ahora voy y salgo con esta entrada pelota... imperdonable, lo sé. Prometo ser más capullo la próxima vez... 

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.

jueves, 11 de octubre de 2012

Aplicaciones Facebook: Las claves del éxito


Sí, programador, a casi todos nos ha pasado en alguna ocasión... Un día te levantas de la cama y una vez recorridos todos los canales de la tele varias veces, hasta que te aseguras de que lo que ponen es la misma basura de siempre, decides... ¡hacer algo de provecho!. Y surge la duda de qué. ¿Limpiar la casa?, no, que estoy empezando a hacer amistad con los seres vivos que están surgiendo de entre la mierda. ¿Hacer la compra?, no, que estamos en crisis, ¿qué hago yo derrochando mientras los pobres niños africanos se mueren de hambre?. ¿Cambiar la bombilla esa que lleva 7 años sin funcionar?, no, porque rompería el frágil equilibrio de luces y sombras que tanto estilo le está empezando a dar a la casa. ¿Poner la lavadora?, no, porque corro el riesgo de que mis maravillosas camisetas a manchas marrones "estilo Rorschach" vuelvan a ser blancas, y ya no pueda usar el truco del test de personalidad para ligar con las "churris"... hmmmm bueno, rascarme la barriga puede valer mientras me decido por algo.

Pero nosotros somos programadores, así que tenemos en nuestra mano hacer algo que sea de provecho y que a la vez mole. Y hoy has decidido... ¡hacer tu primera aplicación Facebook!.

Ya que el proceso de rascado de barriga te ha llevado toda la mañana, tampoco es que te quede tiempo para grandes cosas. Descartaremos por esta vez hacernos ricos. ¿Pero en una tarde te dará tiempo a hacer una aplicación?. Habrá que currárselo un poco, ¿no?, no querrás hacer una gansada absurda.

Regla 1 ("duck soup" rule): no merece la pena hacer una aplicación Facebook que no sea una gansada absurda. Llevaría mucho más trabajo y rompería las expectativas de los usuarios. Si quieres hacer algo que no sea absurdo, ¿por qué lo ibas a hacer en Facebook?

Ok, gansada absurda, pues. Puedes con ello. ¿Cuál puede ser la interacción con el usuario?. ¿Quizá hacer que el usuario rellene un completo test para después hacer un análisis estadístico de...?

Regla 2 ("braindead" rule): ni se te ocurra hacer currar al usuario. El usuario probablemente esté perreando en la oficina, o perdiendo un poco el tiempo en casa para no tener que ponerse a hacer la cena. ¡Lo último que necesita es pensar!

Vale, pues le pones un botoncico al usuario y ya está. O como mucho un test con 3 preguntas tontas para que parezca que estamos haciendo algo. Y si acaso sacamos de su perfil su edad, o su nombre, o cosas así. ¿Pero qué puedes calcular con tan poca información?.

Regla 3 ("the sting" rule): no hay que calcular nada, mucho mejor inventárselo. Es más rápido y el efecto es el mismo. Tranquilo, el usuario no te va a pedir que le devuelvas el dinero

Bueno, bueno, esto está tomando forma... ¿qué tipo de información puedes dar?, te la estás inventando, y leche, ¡estamos en la época de Internet, donde cualquier información puede contrastarse con facilidad en unos segundos!

Regla 4 ("back to the future" rule): fácil, basta conque des informaciones esotéricas que no se puedan verificar de forma científica. Los ejemplos típicos son "adivinar" el futuro o hacer una conexión con otros amigos o con cualquier grupo de cosas o personajes, como por ejemplo "si fuera un hermano Marx cuál sería"

En fin, la aplicación ya casi está. Pero qué poca gracia, ¿no?. ¿Por qué iba a propagarse una aplicación tan tonta como esta?. ¿Por qué iba a ser mejor que las demás?. ¿Por qué a nadie le iban a interesar las tontunas que te inventes?. Supongo que hay que hacer que parezcan reales, ¿no?.

Regla 5 ("liar liar" rule): ¡ni se te ocurra!, ¡sería el mayor error!. Al revés, las respuestas tienen que ser exageradas, e incluso llevadas al extremo. Es la forma de que los amigos del que ha hecho la aplicación comenten como locos, hagan bromas, se tiren los trastos, se deseen suerte, etc. Así conseguirás el objetivo: todos ellos pincharán en la aplicación y la propagarán cual virus zombie.

Siguiendo estas 5 básicas reglas, querido lector, conseguirás el éxito en el Facebook, no ligando (que igual también, oye), sino creando esa aplicación hecha en una tarde de la que todo el mundo habla.

Este "post" está inspirado en una aplicación Facebook que ha demostrado sobradamente su eficacia estos días entre mi círculo de amistades. Pongo una imagen en la que se ve perfectamente de qué va...


Obsérvese la perfecta aplicación de las reglas... ¿cuántos comentarios se pueden hacer con información de este estilo?. Por supuesto, nada de poner que vas a tener 1 coche, 0 hijos, 1 casa y 1 gato, ¡eso no sería "cool", nadie lo comentaría!. ¿Cuánto pensáis que se puede tardar en hacer una aplicación así?. No, no, ¡menos aún!.

Bueno, pues ya está... ya has hecho algo de provecho. Ahora... ¿qué pondrán en la tele?...

lunes, 8 de octubre de 2012

Java: Distribuyendo aplicaciones de escritorio (¿de escri-cuálooo?) con Maven, One-JAR y Launch4J

Cof, cof, cof, ¿recuerdas las aplicaciones de escritorio?. Sí, esos programas que descargabas de Internet y los metías en el disco duro de tu PC para ejecutarlos cuando quisieras. Sí, sí, eso que utilizaba la gente antes de que llegara "la nube" y lo absorbiera todo. Cuando los PCs aún existían, en lugar de los móviles listillos y las tabletas no menos listillas.

Vale, vale, esto aún no es así del todo, pero en poco tiempo es muy probable que este comentario lo hagáis vosotros mismos cuando habléis con el becario jovencito de  turno y activéis vuestro modo "abuelo cebolleta". Así que me he decidido a publicar esta "receta Java" cuanto antes, para que no se quede tan retro como mis batallitas sobre el código máquina del Spectrum. Lo cierto es que aunque pasadas de moda, las aplicaciones de escritorio, ya sean aplicaciones con interfaz gráfica o aplicaciones de consola, siguen teniendo su huequecillo. Y no es menos cierto que distribuir este tipo de aplicaciones es algo que Java siempre ha dificultado enormemente, de una forma más bien absurda. Como en muchos otros aspectos de Java, fue la comunidad open source la que proporcionó las soluciones al problema. Ninguna de ellas es precisamente nueva, pero tampoco las conoce todo el mundo.

El asunto es que Sun pensó en pequeño: "Sólo necesitamos un tipo de archivo en el que podamos meter mogollón de clases y que sea capaz de saber cuál es la clase con el main". Alzó el todopoderoso dedo de la creación, y dio vida al fichero JAR. Esto ya de por sí es una forma perfectamente válida de distribuir una aplicación Java. Si le haces doble click al fichero, te ejecuta la aplicación. Si haces un sencillo script con un java -jar, ya tienes algo sencillo para ejecutar desde consola.

El problema es que ese mismo fichero JAR no sólo sirve para distribuir aplicaciones, sino que también sirve para distribuir librerías. Y si quieres librerías, en Java las tienes a patadas. Por supuesto, podrías desempaquetar las librerías y volver a empaquetarlas junto a tu aplicación en un precioso fichero JAR, y eso funcionaría. Pero es un mecanismo, la verdad, bastante guarro, aparte de que se pueden perder ficheros duplicados, como por ejemplo los ficheros de licencia de las librerías, cuya presencia a menudo es requerida por la propia licencia.

Otra opción es jugar con el classpath para que se incluyan los JAR de las librerías. Puedes hacerlo a nivel de script o, mejor aún, puedes modificar la sección Class-path del fichero Manifest de tu JAR principal. En cualquier caso, a poco que sean unos cuantos te va a salir un churro difícil de manejar, y además es muy fácil que eso te acabe dando problemas. Y estás convirtiendo el script en parte integral del programa, por lo que si alguien necesita modificarlo, dificultará la actualización de versiones. Funciona, pero es sucio, y cuantas más librerías tengas más sucio será. Aun así, es con diferencia el método que he visto más utilizado.

En este contexto, una buena solución es usar One-JAR. One-JAR lo que hace es permitirte crear un JAR que a su vez incluya dentro el resto de JARs. Se comportará como un JAR normal, en cuanto a que puedes hacerlo ejecutable sin problemas, pero además si lo descomprimes verás que dentro están todos los ficheros JAR de librerías, con el nombre y versión de cada una, sus ficheros de licencia, etc. Todo muy muy limpio. Si además añades en el Class-path del fichero Manifest el directorio ".", o algún subdirectorio que vayas a meter en la aplicación, podrás añadir junto al jar ficheros de configuración que el usuario pueda editar y que el código busque a nivel de classpath. Ejemplo típico: el fichero log4j.properties de la librería log4j.

Si además estamos utilizando Maven para la compilación y creación del paquete (y si no lo estamos utilizando, ya estamos tardando en hacerlo), utilizar One-JAR es tan sencillo como añadir esto en nuestro fichero pom.xml:

<project ...="...">
  (...)
  
  <build>
    <plugins>
      <!-- Manifest con Main al hacer jar -->
      <plugin>
        <artifactid>maven-jar-plugin</artifactid>
        <configuration>
          <archive>
            <manifest>
              <mainclass>com.andresviedma.chachiapp.Main</mainclass>
              <addclasspath>true</addclasspath>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      
      <!-- Creación directorio distrib para generar ahí los ficheros -->
      <plugin>
        <artifactid>maven-antrun-plugin</artifactid>
        <executions>
          <execution>
            <id>crear_distrib_dir</id>
            <phase>package</phase>
            <goals><goal>run</goal></goals>
            <configuration>
              <tasks>
                <mkdir dir="${project.build.directory}/distrib">
              </mkdir></tasks>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <!-- Generación fichero OneJar -->
      <plugin>
        <groupid>org.dstovall</groupid>
        <artifactid>onejar-maven-plugin</artifactid>
        <version>1.4.0</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals><goal>one-jar</goal></goals>
            <configuration>
              <onejarversion>0.96</onejarversion>
              <filename>distrib/${project.build.finalName}-all.jar</filename>
              <attachtobuild>true</attachtobuild>
              <classifier>all</classifier>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <!-- Repositorio con plugin OneJar -->
  <pluginrepositories>
    <pluginrepository>
      <id>onejar-maven-plugin.googlecode.com</id>
      <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginrepository>
  </pluginrepositories>
  
  <dependencies>
    <dependency>
     <groupid>com.simontuffs</groupid>
     <artifactid>one-jar-boot</artifactid>
     <version>0.96</version>
     <scope>runtime</scope>
    </dependency>
 </dependencies>
</project>


NOTA: El código que estoy poniendo está probado con Maven 2.0.9, imagino que para otras versiones no habrá que tocar gran cosa, pero avisado quedas. Si no estamos utilizando Maven, crear un One-JAR con Ant por ejemplo también es muy fácil. De hecho crearlo a mano copiando ficheros en directorios y comprimiéndolos también.

¡Hecho! Ya tenemos nuestro precioso fichero JAR enorme, independiente y ejecutable por sí solo, ¡más mono!. Le añadimos un script que haga un sencillo "java -jar xxx", lo metemos todo en un zip y ya lo tenemos.

Ahora bien... esta solución es muy buena por ejemplo para Linux, donde se suele suponer que el usuario no se asusta ante el concepto de script, y estos funcionan perfectamente en cualquier situación, y donde todo el mundo asume que para ejecutar una cosa muchas veces hay que instalar primero otra (el JRE, claro). Sin embargo, si queremos hacer un paquete aún más completo para sistemas Windows, y que no asuste al usuario más inexperto, podemos darle todavía una vuelta de tuerca más. Existen otras soluciones, como por ejemplo JSmooth, pero aquí voy a contar cómo hacerlo con Launch4J.

Al igual que en el caso del One-JAR, la generación de un precioso fichero .exe, con su iconito, su splash y todo, se puede automatizar sin problemas con Maven. Es más, en teoría no necesitas generarlo desde Windows, lo puedes generar incluso desde tu Linux o Mac, y que sea el usuario final el que lo ejecute en Windows (para ello tendrás que tener instalado MinGW). Por último, puedes meterle incluso un JRE dentro del propio fichero EXE, o pedirle que detecte si el ordenador destino tiene uno instalado, y que si no lo tiene dé un mensaje bien clarito para que el usuario se lo descargue. Y una cosita más: para facilitarlo todo, podemos aprovechar el mismo fichero JAR que hemos creado en el punto anterior gracias a One-JAR. Para conseguirlo, vamos a aumentar el POM anterior añadiendo la generación del EXE, con lo que nos quedaría así:

<?xml version="1.0" encoding="UTF-8"?>
<project ...="...">
  (...)

  <build>
    <plugins>
      <!-- Manifest con Main al hacer jar -->
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <mainClass>com.andresviedma.chachiapp.Main</mainClass>
              <addClasspath>true</addClasspath>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      
      <!-- Creación directorios exe y distrib para generar ahí los ficheros -->
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <executions>
          <execution>
            <id>crear_exe_dir</id>
            <phase>package</phase>
            <goals><goal>run</goal></goals>
            <configuration>
              <tasks>
                <mkdir dir="${project.build.directory}/exe" />
                <mkdir dir="${project.build.directory}/distrib" />
              </tasks>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <!-- Generación fichero OneJar -->
      <plugin>
        <groupId>org.dstovall</groupId>
        <artifactId>onejar-maven-plugin</artifactId>
        <version>1.4.0</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals><goal>one-jar</goal></goals>
            <configuration>
              <onejarVersion>0.96</onejarVersion>
              <filename>distrib/${project.build.finalName}-all.jar</filename>
              <attachToBuild>true</attachToBuild>
              <classifier>all</classifier>
            </configuration>
          </execution>
        </executions>
      </plugin>
      
      <!-- Generación de ejecutable Windows .exe con launch4j -->
      <plugin>
        <groupId>org.bluestemsoftware.open.maven.plugin</groupId>
        <artifactId>launch4j-plugin</artifactId>
        <version>1.0.0.2</version>
        
        <executions>
          <execution>
            <id>l4j-clui</id>
            <phase>package</phase>
            <goals>
              <goal>launch4j</goal>
            </goals>
            <configuration>
              <dontWrapJar>false</dontWrapJar>
              <headerType>gui</headerType>  <!-- Console si queremos aplicación de consola -->
              
              <jar>${project.build.directory}/distrib/${project.build.finalName}-all.jar</jar>
              <outfile>${project.build.directory}/exe/ChachiAndrew.exe</outfile>
              
              <!-- Optional, sets the title of the error message box that's displayed if Java cannot be found for instance.  -->
              <errTitle>Chachi Andrew</errTitle>
              
              <!-- Optional, constant command line arguments. -->
              <cmdLine />
              
              <!-- Optional. Change current directory to an arbitrary path relative to the executable. -->
              <chdir />
              
              <priority>normal</priority>
              <downloadUrl>http://java.com/download</downloadUrl>
              <supportUrl />
              
              <!-- Set the process name as the executable filename and use Xp style manifests (if any). -->
              <customProcName>true</customProcName>
              
              <!-- Optional, defaults to false in GUI header, always true in console header. When enabled the launcher waits for the Java application to finish and returns it's exit code. -->
              <stayAlive>false</stayAlive>
              <manifest />
              <icon>src/main/resources/com/andresviedma/chachiapp/resources/chachiapp.ico</icon>
              
              <jre>
                <!-- The <path> property is used to specify the absolute or relative path (to the executable) of a bundled JRE. Sólo si no se quiere que se use la actual -->
                <path />
                <!-- Search for Java, if an appropriate version cannot be found display error message and open the Java download page. -->
                <minVersion>1.5.0</minVersion>
                <maxVersion />
                <!--  Optional, max heap size in MB. -->
                <maxHeapSize>256</maxHeapSize>
              </jre>
              
              <!-- Pantalla de splash -->
              <splash>
                <!-- Necesario que esté en formato bmp -->
                <file>src/main/resources/com/andresviedma/chachiapp/resources/splashChachiApp.bmp</file>
                <!-- Optional, defaults to true. Close the splash screen when an application window or Java error message box appears. If set to false, the splash screen will be closed on timeout. -->
                <waitForWindow>true</waitForWindow>
                <!-- Optional, defaults to 60. Number of seconds after which the splash screen must be closed. Splash timeout may cause an error depending on <timeoutErr>. -->
                <timeout>30</timeout>
                <!--  Optional, defaults to true. True signals an error on splash timeout, false closes the splash screen quietly. -->
                <timeoutErr>false</timeoutErr>
              </splash>
              
              <!-- Información de versión -->
              <versionInfo>
                <!-- Version number 'x.x.x.x' -->
                <fileVersion>0.0.0.0</fileVersion>
                <!-- Free form file version, for example '1.20.RC1' -->
                <txtFileVersion>${project.version}</txtFileVersion>
                <!-- File description presented to the user. -->
                <fileDescription>${project.description}</fileDescription>
                <!-- Legal copyright. -->
                <copyright>(C) Andrés Viedma</copyright>
                <!-- Version number 'x.x.x.x' -->
                <productVersion>0.0.0.0</productVersion>
                <!-- Version number en texto libre -->
                <txtProductVersion>${project.version}</txtProductVersion>
                <!-- Text. -->
                <productName>${project.name}</productName>
                <!-- Optional text. -->
                <companyName>Andrés Viedma</companyName>
                <!-- Internal name without extension, original filename or module name for example. -->
                <internalName>${project.name}</internalName>
                <!-- Original name of the file without the path. Allows to determine whether a file has been renamed by a user. -->
                <originalFilename>ChachiAndrew.exe</originalFilename>
              </versionInfo>
              
              <!-- Mensajes de error que saldrán en caso de producirse -->
              <messages>
                <startupErr>Error al inicio de la ejecución</startupErr>
                <bundledJreErr>Esta aplicación estaba configurada para usar una Java JRE pero no existe o está corrupta.</bundledJreErr>
                <jreVersionErr>Esta aplicación requiere una versión distinta de JRE.</jreVersionErr>
                <launcherErr>No hay ninguna JRE instalada o está corrupta.</launcherErr>
                <instanceAlreadyExistsMsg>La aplicación ya se está ejecutando en otro proceso.</instanceAlreadyExistsMsg>
              </messages>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <!-- Repositorio con plugin OneJar -->
  <pluginRepositories>
    <pluginRepository>
      <id>onejar-maven-plugin.googlecode.com</id>
      <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
  </pluginRepositories>
  
  <dependencies>
    <dependency>
      <groupId>com.simontuffs</groupId>
      <artifactId>one-jar-boot</artifactId>
      <version>0.96</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>


Todavía podemos darle alguna vuelta más. Por ejemplo, podemos hacer un assembly sencillo que genere un ZIP en el que se meta el .exe (o el One-JAR) junto a ficheros de ayuda, licencia, configuración o lo que queramos. O podemos crear un instalable Windows que cree los iconos en el menú de inicio y utilice ese mismo ejecutable creado anteriormente con Launch4J. Para eso podemos usar sistemas como NSIS que, ¡vaya hombre!, resulta que también tiene integración con Maven.

El caso es que usando Maven y tocando cuatro cosas en tu pom.xml, puedes automatizar por completo la creación de un paquete de distribución de tu aplicación de escritorio de una forma bastante cómoda.

Ahora te queda la parte más chunga, querido lector: que en un mundo dominado por la nube, el HTML5 y las aplicaciones para móviles... alguien se interese por tu aplicación de escritorio.

Cof, cof.



miércoles, 26 de septiembre de 2012

En busca del UML perdido

Años 90. Se puede considerar que por aquel entonces, en esto del desarrollo, estábamos en la época de las metodologías. Mentes pensantes se estrujaban las meninges para dar con el método perfecto que pudiera llevar a cualquier mindundi que no supiera nada a hacer programas, qué digo a hacer programas, ¡a hacer programas mantenibles y bien hechos!. Alguno igual hasta suspiraba porque su metodología fuera tan perfecta que los propios ordenadores fueran capaz de hacer sus propios programas, ellos solitos, mientras el programador daba cuenta de una jarra de cerveza. Se pensaba que si la metodología era buena, el programa resultante tenía que ser bueno.

Durante muchos años, la "cascada" era el modelo dominante, dentro de esas metodologías. Primero un señor A pensaba qué tenía que hacer el programa, y lo escribía todo en un documento. Luego, otro señor B pensaba cómo se iba a hacer lo que indicaba el señor A, y lo escribía todo en otro documento. Luego, el señor C, también llamado "el pringadete de turno" tenía que hacer el programa como habían dicho los otros dos. En la práctica, en cuanto el señor C empezaba a meterse en faena, se empezaba a dar cuenta de que había cosas que no cuadraban, otras que se habían pasado por alto, otras que no se entendían, otras que no tenían sentido, etc. Resultado: el proyecto se retrasaba horrores, el señor C hacía horas como un campeón y le tocaba tomar decisiones que no le correspondían, y los maravillosos documentos y esquemas realizados por los señores A y B quedaban anticuados a las dos semanas de trabajo de C. Al final, al cliente se le daban unos tochos de documentación, que le importaban un pepino y ni se molestaba en mirarlos para darse cuenta de que no estaban actualizados, y un programa que (con un poco de suerte) funcionaba pero se acababa convirtiendo en algo imposible de mantener (lo que viene a llamarse efecto bola de nieve). En definitiva, este método normalmente no funcionaba. Es más, esto causaba un divorcio entre el mundo académico y el mundo real, que necesita soluciones prácticas y eficientes para llegar a una solución.

Dentro de esa vorágine, aparecía el paradigma de la programación orientada a objetos. La mayor gracia de los objetos es que facilitan manejar un concepto que ya estaba haciendo mucha falta manejar: la incertidumbre. Vale, supongamos que somos humanos. Supongamos que no conocemos bien lo que se necesita hacer, que el desarrollo conlleva que el programador vaya aprendiendo gradualmente qué es lo que realmente se necesita. Supongamos que además, no conocemos qué se va a necesitar en el futuro, como van a evolucionar las necesidades y cómo van a ir cambiando las cosas. Supongamos, incluso, que esto que hemos hecho podemos acabar utilizándolo como parte de otros programas más grandes, reutilizándolo. En ese caso, necesitamos ser capaces de hacer estructuras y componentes que sean lo más flexibles posible. Eso es precisamente lo que permitían los objetos.

Por supuesto, como buena época de metodología en la que estábamos, rápidamente aparecieron más mentes pensantes buscando el método mágico con el que crear programas orientados a objetos fuera tan fácil que pudiera hacerlo hasta un niño de 3 años dormido y con las manos atadas a la espalda (y peor aún, en Lunes). Es más, aprovechando el vacío existente, cada mente pensante se inventaba sus propios diagramas para hacer el diseño del programa, con cajitas, nubecitas, flechitas o lo que fuera. Un carajal, vaya.

Un buen día tres de esas mentes pensantes que tenían sus propios métodos y notaciones (Booch, Rumbaugh y Jacobson) hicieron equipo, con el simpático nombre de los "three amigos", y en 1997 crearon una notación única para hacer diseño orientado a objetos, con ánimo de convertirse en un estándar (como así fue) y de que encajara en cualquiera de los métodos mágicos existentes. Había nacido el UML. La importancia de esto es grande, ya que con el UML se separaba el lenguaje de modelado de la metodología que se siga para obtenerlo, y se definieron los conceptos que se iban a manejar en el diseño orientado a objetos. Si tú veías un diseño orientado a objetos hecho en UML lo entenderías, independientemente de cómo se hubiera llegado a ese diseño. Y un diseño hecho en UML te da una perspectiva buenísima de cómo se ha pensado un programa, cómo se ha estructurado, cómo se ha diseñado. Esa perspectiva funciona tanto para el que lo está diseñando, que según lo va haciendo lo va entendiendo mejor, como para el que tiene que entenderlo para  modificar el programa más adelante y hacerle cambios sin volverse loco. Ayuda a pensar, ayuda a hacer entender.

No penséis que esta colaboración de los "amigos" vino propiciada por el buen corazón de estos tres tipos. Si fuera así, quizá habrían contado con otros teóricos notables de la época, como Martin Fowler ó Erich Gamma, que además habían hecho contribuciones importantes al empezar a proponer algo distinto a oooootra metodología mágica más: fomentar el uso de patrones. Un patrón no es más que un ejemplo "bien hecho" de cómo resolver de forma adecuada un problema común. O sea, básicamente permite que aprendas a diseñar "copiando" otras soluciones. Por tanto, no llegas a una solución buena por un método mágico, sino que llegas a ella copiándola de otro caso parecido, y al hacerlo, la aprendes y la haces tuya. Es como el que en arquitectura inventó la puerta, o la escalera de caracol, y luego todos copiaron la idea, o como el que inventó una forma innovadora de pintar los paisajes en los cuadros. Eso funciona.

Como decía, el motivo detrás de esta gran amistad tenía que ver con una empresa que había visto el filón que se le presentaba: Rational. Esta empresa contrató a estos tres amigos para impulsar la venta del que lanzaron como su producto estrella: Rational Rose. Sospecho que la jugada les salió bastante bien durante varios años. Sé que aunque mucha gente lo pirateaba, también había muchas empresas que pagaron licencias del producto, y realmente se llegó a "poner de moda". Los "amigos" no se quedaron ahí, y como buenos metodólogos, rápidamente inventaron también una metodología "única": el Proceso Unificado. El Proceso Unificado iba más allá de la cascada, y promovía el desarrollo basado en "iteraciones", en las que cada iteración venía a ser una mini-cascada.

Ahora, volvamos al presente (no se vaya a convertir esto en otra entrada en plan "abuelo cebolleta"). Han pasado ya unos cuantos añitos y se puede decir que los objetos han triunfado, sobre todo gracias a Java. Sin embargo, aunque se programa mucho con objetos, pienso que cada vez se ven menos diseños con objetos. La propia palabra "diseño" se usa hoy en día fundamentalmente para el diseño gráfico, más que para el diseño de software.

¿En qué momento se empezó a perder el diseño, si gracias a UML ya teníamos lo mínimo necesario, que es una notación común, y herramientas capaces de crear esos diseños con facilidad, y hace un rato he hecho un canto a las maravillas del diseño con UML?. ¿Qué pasó?. ¿Realmente hemos perdido algo, era útil, o era más bien prescindible?. ¿Todavía podría convertirse en algo práctico?. ¿Cómo?.

Daré mi opinión sobre todo esto en la segunda parte de esta apasionante saga, con el título provisional de "Herramientas y el UML maldito". Manteneros atentos y tened paciencia. Al fin y al cabo, cuando la serie acabe puede que el UML os haga cambiar vuestra forma de programar...

cookie consent