Diseñando una arquitectura (II/IV): Alternativas de solución

Estaba claro que la situación era mejorable. La industria llevaba años generando grandes productos que no se estaban aprovechando. Ahora era el momento de elegir e implantar.

II. Alternativas de solución

He de agradecer que se confió en mí plenamente -espero que no haya habido demasiados arrepentimientos sobre esto-. Se me exigió informes, pruebas de viabilidad, etc., pero la libertad de la que disfruté fue máxima. Se mantuvieron las siguientes restricciones:
  • El entorno sería J2EE. Java es con lo que se trabaja en todo el departamento, y así iba a seguir siendo. Esto favorece la movilidad de personal, facilita la formación, la reutilización de código, etc.
  • El SGBD sería Oracle. Es lo que se ha venido usando siempre, es de lo que se cuenta con personal cualificado, soporte, etc.
  • El servidor de aplicaciones sería el Sun Java System Application Server 8.1. Esto viene impuesto por la superorganización.
Entorno de desarrollo
Lo primero fue cambiar el entorno de desarrollo. Se venía usando JDeveloper por inercia, por ser lo utilizado en la superorganización, pero no respondía a ninguna restricción real. La principal razón a la que nos agarramos para el cambio fue el servidor de aplicaciones. El JDeveloper integra OC4J y no había forma de hacerlo funcionar contra el SJSAS 8, que era lo deseable. Además, para cualquiera que haya usado otro IDE el OC4J es antediluviano. Aunque sobre el papel las características sean similares, en el día a día deja mucho que desear.
La política de la empresa es tender hacia el Open Source y a evitar gastos innecesarios, así que se barajó Eclipse y NetBeans. El primero es al desarrollo como Firefox a los navegadores: cuenta con infinidad de plugins útiles. El segundo, sin embargo, tiene un killer, Matisse. Una buena parte del desarrollo se hace en aplicaciones standalone de escritorio, con swing, y al parecer Matisse es infinitamente mejor que otros diseñadores gráficos. Yo ni los había usado ni los iba a usar, y la decisión no me correspondía. Los responsables de ello lo querían a toda costa, pero también deseaban Eclipse, debido a ciertos plugins. Tras descartar usar dos entornos diferentes, se optó por MyEclipse. Este entorno es Eclipse con ciertas mejoras desarrolladas específicamente para él, e integra Matisse, por lo que era una solución ideal. El coste es muy bajo y las primeras pruebas resultaron satisfactorias, así que fue el elegido. Eso nos permitió trabajar con el servidor adecuado, además de disfrutar de todo lo que se desarrolla para él.

Persistencia
Hibernate me parece LA razón para desarrollar en Java. Es potente, flexible, completo, eficiente... Desde que lo usé por primera vez no se me ocurre comenzar un desarrollo sin él. Escribir SQL por defecto me parece algo totalmente atrasado e indeseable. Está claro que en ciertas ocasiones es lo mejor y se debe recurrir a ello, pero la potencia de poder guardar y recuperar árboles de información completos sin necesidad de escribir una consulta es inigualable. No sólo por el hecho de escribir las consultas, sino porque el no tener que escribirlas hace que no haya que modificarlas ni mantenerlas nunca. Esto, que parece perogrullo, no lo es. Si has escrito las consultas, un cambio en el modelo es dramático. Hibernate hace que ni siquiera sea necesario pensar en el modelo de datos. Piensa en el modelo de clases, piensa en términos de objetos, que es lo que la aplicación va a manejar en último término.
A día de hoy la aplicación que ha servido de arranque a esta nueva infraestructura gestiona datos de unas 140 tablas de varios esquemas, tanto propios como comunes. Sin Hibernate esto no habría sido posible.
Toplink es una alternativa similar, pero por lo que pude leer, más limitado. Se ciñe más al estándar (o el estándar a él), asumiendo ciertas limitaciones que Hibernate se salta mediante extensiones propias.
Hay otros motores diferentes que también son viables, notablemente iBatis. Sin embargo, la productividad que se obtiene no tiene nada que ver.

Unido a Hibernate se adoptaron otros proyectos hermanos: Hibernate Validator e Hibernate Annotations. El primero permite definir validaciones mediante anotaciones en los modelos, y el segundo, incorporar la configuración de persistencia en los propios modelos.

Middleware
Por aquél entonces la elección natural era Spring. Era ya un framework completo, estable, probado... Google sacó su Guice más tarde, y Seam acababa de nacer. Spring nos resolvería la organización de la capa de lógica de negocio, simplificaría las pruebas, servicios web...
El uso de Spring nos llevó además al uso de Acegi (ahora llamado Spring Security) como sistema de seguridad. Este, a su vez, a instalar un servidor CAS. Todo esto nos ha permitido implantar un sistema de single sign on del que se llevaba hablando mucho tiempo.

Pruebas
Con las pruebas tiramos por lo directo: JUnit 4. Había oído hablar de otras alternativas, pero hasta la fecha en la organización no se programaban pruebas en absoluto, así que nos contentaríamos con que consiguiésemos acostumbrarnos a usar este sistema con cierta soltura.
Adicionalmente pronto vimos que sería conveniente el uso de Unitils. Por aquel entonces Spring no soportaba JUnit 4 correctamente, y esta librería facilitaba la inyección de los beans.

Vista
Otra de las grandes justificaciones para el cambio fue la introducción de Ajax, como valor añadido para los usuarios. De nada nos serviría hacer mejor "las tripas" de la aplicación si el usuario no veía novedades.
IMHO (como siempre ;) ) si piensas en Ajax en Java tienes que pensar en JSF. Al menos por aquél entonces. En mi opinión, el planteamiento de orientación a componentes de JSF lo hace perfecto para esa tecnología. Para explicar esta opinión, siempre hablo de Struts como división "vertical" y JSF como "horizontal". Lo natural es que una solicitud en Struts vaya a un Action que realice un procesamiento y muestre una página (imagino esta generación del código como un proceso de arriba a abajo).  En JSF, sin embargo, "trozos (horizontales) de página" tienen entidad propia. Tienen comportamiento y orígenes de datos propios. Está claro que con ambos sistemas se puede hacer, y de forma correcta, pero por aquél entonces parecía que lo más adecuado era JSF.
Como implementación del estándar se optó por MyFaces, debido principalmente a que un componente (que posteriormente se descartó), FCKFaces, dependía de él. Sobre MyFaces usamos también Tomahawk y Sandbox, que incorporan componentes interesantes. Pronto quedó claro que Facelets era una decisión obligada al hacer JSF (aunque nunca he dejado de echar de menos Tiles, que junto al Validator me parecían la verdadera razón para usar Struts). Para hacer pseudocomponentes con "trozos" de páginas es muy útil, y también para organizar las páginas como plantillas (aunque no es ni de lejos tan potente como es Tiles). Todo esto estamos hablando de JSF 1.1, debido a la versión del servidor.
La gran duda vino a la hora de elegir la librería Ajax. Tras dar tumbos entre varias opciones quedó claro que había dos grandes contendientes: Ajax4JSF (con RichFaces) e ICEFaces. ICEFaces tenía un conjunto de componentes mayor, más completo. Por el contrario, Ajax4JSF me parecía más flexible. Ambos tenían una intensa actividad. El ritmo de mejoras de Ajax4JSF parecía mayor, debido principalmente a sus obvias carencias respecto a la competencia (ni tenía un componente de calendario por aquél entonces). Ambos estaban bajo la tutela de JBoss, así que la continuidad parecía garantizada. A la hora de probarlos, éste no me dio ningún problema al combinarlo con otras librerías, mientras que ICEFaces sí. Al ser incompatibles entre sí, opté por el primero, aunque ICEFaces seguramente también habría sido una decisión válida. Para las cosas en las que estas librerías se quedaban cortas las completamos con componentes hechos con Facelets encapsulando código de Dojo.

Por tanto, íbamos a pasar de JDeveloper con OC4J y servlets a la vieja usanza a MyEclipse sobre SJSAS 8.1 y Oracle, desarrollando con Hibernate, Spring, JUnit, JSF y Ajax4JSF/RichFaces. Está claro que el cambio iba a ser grande. En la siguiente entrega iremos recapitulando sobre los problemas que nos han aparecido al hacerlo, los aciertos y los errores.

Posted by Juan Ignacio Sánchez Lara 0:24  

5 Comments:

  1. Martín said...
    Muy interesante Juan Ignacio. Espero que publiques pronto las siguientes dos entregas.

    Probablemente discrepase un poco en lo de JSF. Mis experiencias no han sido demasiado buenas con esta tecnología y tiendo a derivar a otras alternativas más simples. El modelo que proponen es elegante, pero no se materializa como nos esperaríamos con grandes diferencias entre las diversas librerías e incompatibilidades entre las implementaciones de diferentes servidores. Todo eso hace que los desarrolladores normalmente sufran bastante al intentar utilizarlo. Pero esa es mi experiencia claro...
    seiju said...
    Yo discrepo totalmente en la elección J2EE, pero bueno, supongo que será para la típica cárnica que contrata a gente sin parar y que tiene programando a los que considera peor (cualquier que sea considerado "bueno" lo ascienden y se pone a hacer papeles como esta serie de post).

    En tales escenarios, siempre se escoge j2ee para que puedan salir los proyectos adelante, al menos alguno de vez en cuando. Pues cualquier otra tecnología que requiere un mínimo de maña al programar sería un total desastre.
    Nacho said...
    En mi opinión J2EE es más pesado que otras, y con un arranque más costoso, pero en general más completo. ¿Tú qué habrías elegido, seiju?
    seiju said...
    Pues elegiría nada. Según para qué problema, se plantea qué usar.

    Si es una aplicación web, al menos para el frontend, en un lenguaje de script sin duda. Desde luego que aplicaciones web con j2ee, no. (Lo cual, repito, no quita el tener un backend corriendo en tus jvm)

    J2EE de primera puede ser muy pesado y complejo (innecesariamente complejo, es como WS-*), pero requiere, por parte del programador, pensar mucho menos, pues esta mucho más limitado.

    A un programador una vez le pongas todo su entorno para programar su primer controlador en jsf y cual es el flujo de acciones que hay que seguir, ya puede empezar a picar teclas como un autómata. Cualquiera te sirve.

    Ahora pon a ese mismo programador en un lenguaje de script que requiere ser mucho más metódico, las barbaridades y caos que puede llegar a crear serían considerables (ejemplo extremo, perl).
    Nacho said...
    Al escribir este tipo de entradas veo que casi se puede dividir a los lectores entre los que obviamos las alternativas a J2EE y los que lo desprecian (al 100% o parcialmente, como seiju).

    No digo que ninguna de las dos posturas sea la correcta, pero yo me he adherido a la primera por lo siguiente. Ceñirse a una arquitectura común para todas las aplicaciones a desarrollar...
    -Reduce los costes de formación.
    -Facilita la composición del equipo: si sólo me puedo permitir contratar n personas, me es más flexible que todas tengan un perfil similar (mejor movilidad, facilidad en la contratación...).
    -Reduce la complejidad de la infraestructura, al ser común (mismos servidores, por ejemplo).
    -Facilita la integración. Es más fácil echar a andar un proyecto con una pila común (como Seam) que mezclar tecnologías.
    -Reutilización de código entre proyectos.
    -Tengo que admitir que también por inercia: es lo que he visto (cárnicas-consultorías y administración, principalmente).

    Ya partiendo de la base de una infraestructura común, J2EE tiene las siguientes ventajas (en mi opinión, como siempre):
    -IDEs bastante completos.
    -Librerías para (casi) cualquier cosa.
    -En general, buena documentación y soporte.
    -Es el perfil más frecuente en los programadores.
    -Arranque lento, pero productividad creciente con el tamaño del proyecto.
    -Menos exigente con el programador (como indica seiju en el comentario). Hay que ser realistas, en general es una ventaja facilitar que los programadores se rijan por unos límites. Como siempre, se puede hacer un diseño y estructura perfectos con PHP y una castaña con Java, pero las propias limitaciones del lenguaje favorecen lo contrario.

    Comencé el desarrollo web con PHP, hace bastantes años. Siempre he pensado que para proyectos pequeños el scripting es lo mejor, pero que para proyectos empresariales, las ventajas de J2EE son claras. He leído algo sobre otros más nuevos, como Ruby on Rails, y sí, con poquísimo esfuerzo haces el 70% de la funcionalidad de la aplicación, pero el otro 30% es costoso y tira por la borda las ventajas de las convenciones que te han permitido llegar al 70% sin esfuerzo. Con J2EE (bien hecho) suelo ver que llegar a la primera página funcional cuesta muchísimo, pero que las siguientes prácticamente salen solas, y por el camino se ha hecho un trabajo nada despreciable.

    Como siempre, dos buenos programadores de <ponga aquí su lenguaje favorito> van a hacer un trabajo mucho mejor que 4 programadores mediocres en J2EE.

    Estoy de acuerdo con seiju en que a menudo es innecesariamente complejo (por amor de Dios, ¿para hacer logging es normal la complejidad de commons-logging + Log4J/SDK...?), pero a la larga, desde el punto de vista de la empresa, me parece mejor.

    Insisto, si dispusiese de diez cracks que saben mucho y aprenden rápido, apasionados con el trabajo, etc, lo mejor sería elegir lo mejor para cada caso. Sin embargo, eso no me ocurre (o no está en mi mano conseguirlo), por lo que lo que busco es lo mejor teniendo en cuenta todos los factores.

Post a Comment