domingo, 20 de julio de 2008

Introducción a Spring Framework

Spring es un framework open source creado por Rod Johnson, el cual fue inicialmente descrito en su libro “Expert One-on-One: J2EE Design and Development”. El objetivo de Rod Johnson era implementar un framework que permitiese desarrollar aplicaciones empresariales de manera más fácil y rápida, utilizando POJOs (Plain Old Java Object) para lograr cosas que antes eran solamente posibles con EJBs.

Uno de los principales objetivos de Spring es no ser intrusito. Esto quiere decir, que aquellas aplicaciones configuradas para utilizar “Beans” mediante Spring no necesitan depender de interfaces o clases de Spring, obteniendo su configuración a través de las propiedades de sus "Beans".

Este concepto puede ser aplicado a cualquier entorno, desde una aplicación J2EE hasta un applet.

Spring está compuesto por un conjunto características, las cuales están agrupadas en seis módulos principales:



El paquete “Core” es la parte más fundamental del framework ya que provee a este, las características de Inversión de Control (IoC) y Inyección de dependencias (ID). El concepto básico dentro del “Core” es el “BeanFactory”, el cual provee una sofisticada implementación del “Patrón Factory”, que remueve la necesidad generalizada de “Singletons” y nos permite desacoplar la configuración y especificación de las dependencias de nuestra lógica de programación.

El paquete “Context” está construido sobre una solida base provista por el paquete “Core”, el cual proporciona un medio de acceso a los objetos contenidos en el framework de forma tal, que recuerda en cierta medida a la manera en cómo trabaja el registro JNDI. Este paquete hereda algunas características del paquete “Beans” y añade soporte para internacionalización (I18N), propagación de eventos, carga de recursos y la transparente creación de contextos, como por ejemplo, un “Servlet Container”.

El paquete “DAO” provee una capa de abstracción a JDBC, eliminando la tediosa codificación propia de JDBC y el parseo de los códigos de errores específicos de cada proveedor de base de datos. Así también, este paquete proporciona mecanismos de manejo de transacciones tanto programáticamente como declarativamente, cuyo manejo no está restringido a clases que implementen algún tipo de interfaz especial, sino que también está pensado para cualquiera de nuestros POJOs.

El paquete “ORM” provee una capa de integración con las APIs más populares de “Mapeo Objeto-Relacional”, tales como JPA, JDO, Hibernate y iBatis. Usando este paquete nosotros pidremos utilizara cualquiera de estos ORM en combinación con todas las otras características que Spring ofrece.

El paquete “AOP” de Spring, provee una implementación para la programación “Orientada a Aspectos” compatible con el “AOP Alliance” que nos permite definir, por ejemplo, interceptores a un método (method-interceptors) y puntos de corte (pointcuts) para desacoplar limpiamente algunas funcionalidades implementadas en el código que lógicamente deberían conversar por separado.

El paquete “Web” de Spring provee características de integración orientadas a la Web, tales como funcionalidades para la carga de archivos, la inicialización del contenedor IoC usando “Servlet Listeners” y un contexto de aplicación orientado a la web.

El paquete “MVC” de Spring, provee una implementación del patrón MVC (Moldeo-Vista-Controlador) para las aplicaciones web. Spring MVC provee una limpia separación entre el código del modelo de dominio y los formularios web, integrándose a todas las otras características que este framework entrega.

Ejemplo Basico

Para poder comenzar a desarrollar en Spring lo primero que necesitamos es descargarnos la versión 2.5.5 desde www.springframework.org.

En la sección de “download” encontraran tres tipo de archivos a descargar: Spring 2.5.5 (spring-framework-2.5.5.zip), Spring 2.5.5 incluyendo la documentación (spring-framework-2.5.5-with-docs.zip) y Spring 2.5.5 incluyendo todas las dependencias (spring-framework-2.5.5-with-dependencies.zip). Para este ejemplo y los futuros ejemplos, necesitaremos la última de estas tres opciones.

Una vez descargados los archivos, procedemos a crear el proyecto. Para este caso, tenemos varias opciones: podemos utilizar Netbeans 6.x el cual ya incluye soporte para Spring, Eclipse 3.x al cual se le debe instalar Spring IDE o IntelliJ el cual también incluye soporte para Spring.

En este caso utilizare IntelliJ para los ejemplos.

Primero creamos el proyecto seleccionado la opción “File --> New Project…”. Luego seleccionamos la opción “Create Project from scratch” y presionamos el botón “Next”.



A continuación, ingresamos el nombre del proyecto, que para nuestro caso será “SpringBasico” y presionamos el botón “Next”.



Luego, seleccionamos la opción “Create source Directory” y presionamos el botón “Next”.

Por último, seleccionamos que la tecnología deseada para utilizar en el proyecto es “Spring” y presionamos el botón “Finish”. Con lo que se nos construirá la estructura básica de nuestro proyecto.



El único problema, es que la última versión de IntelliJ IDEA solamente tiene soporte hasta la versión 2.0.7 de Spring, razón por la cual necesitaremos cambiar la librería “Spring.jar” por la versión que nosotros descargamos.

Para esto, nos posicionamos sobre el proyecto, presionamos el botón derecho del mouse y seleccionamos la opción “Module Settings”.



Luego, en las opciones de “Project Settings” seleccionamos “Libraries”. Es aquí donde cambiaremos el nombre de nuestro paquete de librerías y modificaremos el “Spring.jar”.

El primer paso será cambiar el nombre del paquete “Spring-2.0.7” por “Spring-2.5.5”. Luego, seleccionamos la ruta del archivo “Spring.jar” y presionamos el botón “Detach”. Por último, presionamos el botón “Attach Classes…”, seleccionamos el archivo “Spring.jar” que se encuentra en la carpeta “dist” de la versión que descargamos anteriormente y presionamos el botón “Ok”.

Para finalizar, presionamos el botón “Apply” para que confirme y actualice todos los cambios, y presionamos el botón “OK”.

El último cambio lo deberemos realizar sobre el archivo “spring-config.xml”. Como IntelliJ solamente tiene soporta para Spring 2.0.7, la definición XSD de este archivo es para la versión 2 de Spring. Por esta razón, deberemos cambiar esta por la versión 2.5.



Para nuestro primer ejemplo, desarrollaremos una idea simple que nos permita ver algunos de los beneficios básicos de Spring.

Imaginemos que necesitamos construir un robot, al cual le ensamblaremos un par de piernas, un par de brazos y una cabeza. Una primera propuesta a nuestro problema sería la siguiente:











El problema con esta implementación es que el código esta “Altamente Acoplado”. Que sucedería si decidimos cambiar la implementación de un brazo? No solamente tendríamos que modificar la clase “BrazoImpl”, sino también la clase “RobotImpl”. Es aquí donde la inversión de control “IoC” y la inyección de dependencias “ID” nos ayudan (más información de IoC y ID la pueden encontrar aquí).

El primer cambio que tendremos que realizar al código, es que cada pieza del robot deberá implementar una interfaz, con lo cual estaremos definiendo un contrato para cada una de estas piezas, y en el caso de que necesitemos diseñar un nuevo brazo o una nueva pierna, simplemente deberemos implementar la interfaz asociada al tipo de pieza.

















Pero quien se encargara de ensamblar el robot? Aquí es donde Spring entra en acción. En el archivo “spring-config.xml” definiremos cada una de estas piezas como “Beans” de Spring.



Como podemos observar, para definir un bean en Spring se utiliza el tag “bean”, al cual se le asigna un “id” único y la clase que define al bean.

Utilizando el tag “property” se puede inyectar un valor al bean. El atributo “name” es el nombre del atributo de la clase que tiene definido un método set en el bean, y el atributo “value”, es el valor que se le inyectara a este bean a través del método set.

Ahora, nuestra clase Test es mucho más simple:



Hasta aquí todo bien, pero.....……que sucedería si tuviéramos que definir 60 beans que representen a algunos objetos del dominio de nuestra aplicación, los que a su vez dependen de 15 objetos de servicios o cualquier otra cosa. Lo único que conseguiríamos sería un gran archivo XML con muchas definiciones de beans.

Una solución sería dividir este XML, en XMLs más pequeños, pero igual seguiríamos con el problema de que en la medida que se necesiten nuevos bean se seguirán definiendo nuevos archivos XML.

Con la versión de Spring 2.5 tenemos una mejor opción, el uso de anotaciones!!. En esta versión, Spring provee un conjunto de anotaciones que resuelven la dependencia de los objetos sin tener que utilizar XML.

Veamos un ejemplo de esto:

















La anotación "@ Autowired" le informa a Spring, que deberá inyectar automáticamente la dependencia, basado en el tipo definido como Autowired (para nuestro caso, las piezas del robot).

Spring también nos permite definir que objeto será inyectado basándose no solamente en su tipo, sino también utilizando el nombre del bean, a través de la anotación "@ Qualifier".

Pero como le definimos un nombre a los beans? Utilizando la anotación "@Component". Con esta anotación, registramos un nuevo bean que se encuentra disponible para ser inyectado por el contenedor de Spring.

Con estas anotaciones, ya no es necesario definir los "Beans" en un XML.

Ahora, solamente nos queda decirle a Spring, que los bean se encuentran definidos utilizando anotaciones, para lo cual nuestro XML de configuración se reduce a esto:



Para nuestro test utilizaremos JUnit integrado a Spring:



Con este simple ejemplo ya podemos ver algunos de los conceptos básicos de Spring.

En el próximo post veremos las diversas opciones de configuración de los Beans utilizando XML y algunos conceptos básicos del “Core” como el "BeanFactory".

Si alguien quiere mas información sobre el paquete “JDBC”, José Miguel Selman está desarrollando una excelente serie de artículos introductorios que pueden encontrar aquí.

martes, 8 de julio de 2008

El patrón "Memento" - Parte V

Cerebro se siente preparado para llevar a cabo su malvado plan. Tiene los conocimientos teóricos, tiene los conocimientos prácticos, pero hay tantos detalles que pulir antes de lanzarse a la conquista del mundo!.

En los ejemplos anteriores, hemos visto como Cerebro ha implementado el “Patron Prototype” (para crear su ejército de robots clones), el “Patron Extension Objects” (para asignarles sus roles), el “Patron Command” (para asignarles las ordenes), y el ”Patron Observer” (para implementar el sistema de comunicaciones). Parece que Cerebro ha estado bastante ocupado implementando patrones, pero ha sido suficiente?. NO!!.

Si recuerdan el “Patron Observer”, dejamos a los robots “Mazinger Z” y “El Vengador” en el instante previo al ataque final. Están esperando a recibir la orden de ataque. Cada robot esta alerta, escuchando la radio, esperando escuchar la señal secreta, para abandonar su posición y lanzarse a cumplir las órdenes recibidas.

Cerebro está a punto de presionar el botón de "Atacar", cuando de repente se da cuenta de que algo no está bien. Qué pasa si me veo obligado a dar la orden de retirada a mis tropas?. No es que mi plan vaya a fallar (después de todo soy un genio del mal), pero ya se sabe, no se puede confiar en los subordinados, y que pasa si tengo que cancelar el ataque cuando mis huestes ya han comenzado a avanzar?.

Ciertamente, Cerebro es un genio. Se ha dado cuenta de un sutil error en su plan. Qué pasaría si tiene que dar la orden de cancelar el ataque cuando sus tropas ya han abandonado su posición inicial?. Bueno, ha implementado un mecanismo de comunicaciones, así que puede mandar la señal secreta de retirada, no?. Pero hay un problema; los robots “Mazinger Z” y “El Vengador” no implementan un buen sistema del manejo de la memoria (sabía que no tenía que instalarles Windows!!!!).

La cuestión es complicada. Un robot “Mazinger Z” y “El Vengador” no tienen buen manejo de la memoria. Solo pueden recordar una cosa a la vez. Por tanto, pueden recordar que tienen que atacar, que tienen que moverse hacia algún lugar, pero en cuanto se meten esa información en la memoria no son capaces de recordar nada más.

Dicho de otra forma, Cerebro les puede decir que vuelvan a su posición original, pero eso no va a servir de nada, porque no se acuerdan de cuál era su posición original.

Peeeeeero, Cerebro recuerda vagamente, como entre una nebulosa, haber leído algo del “Patron Memento” de su gurú “Martin Fowler”.


Qué pasaría si cada robot “Mazinger Z” y “El Vengador” fuera capaz de escribir en un cuaderno su posición inicial, y entregara ese cuaderno a su Sargento?. Y si el Sargento guardara esos cuadernos, y se los entregara a sus propietarios en el caso de que necesitasen volver a las posiciones iníciales?. Problema resuelto!. Es perfecto!. Las ovejas y las vacas solo tendrán que recordar una posición (la posición hacia la que se supone que tiene que ir, sin importar si están atacando o están en retirada), mientras una entidad externa les guardara la información que necesitaran para retirarse.

Pero cómo puede un robot “Mazinger Z” o “El Vengador” guardar su información relevante en un cuaderno?. Fácil, cada robot será responsable de crear una instancia de la clase en la que se va a guardar su información interna, y la entregara a su sargento.



Un momento!. Cerebro se ha dado cuenta de que hay un punto débil en su plan. Si el Sargento guarda los cuadernos con las posiciones iníciales de los robots, hay riesgos de seguridad. Qué pasa si los enemigos roban esa información?. O incluso peor!!. Y si los enemigos no roban esa información, pero la sustituyen por información falsa?. Pero……un momento!. Si la información contenida en los cuadernos estuviera encriptado, o solo fuera accesible por los robots, el problema estaría resuelto, nadie podría cambiarla!.

Por tanto, para evitar posibles cambios en esa información, Cerebro va a tomar dos medidas drásticas. Por un lado, todos los valores guardados en la clase MazingerZMemento solo se podrán asignar a través del constructor. De ese modo, Cerebro se asegura que solo se podrán asignar al crear la clase, y nunca después.

Pero desgraciadamente, no es suficiente (es tan difícil conseguir un buen plan…uffff). Cerebro quiere evitar que la información guardada en el “Memento” sea modificada. De hecho, quiere que solo sea el robot “Mazinger Z” o “El Vengador”, el que pueda crear su memento correspondiente, y asignar sus valores. De esa forma, puede asegurarse de que nadie modifique esa información.

Hacer eso en Java es bastante fácil. Basta con colocar la clase MazingerZMemento en el mismo package que la clase "MazingerZ", y hacer tanto su constructor como sus variables de clase protected. De esa forma, solo pueden crear instancias de esa clase otras clases que estén en su mismo paquete.

Por tanto la clase “MazingerZ” es:







Cerebro lo ha conseguido de nuevo!!. Ha sido capaz de encapsular el estado interno de un objeto en otro objeto distinto, y encapsularlo tan bien que ese segundo objeto solo puede ser utilizado por el objeto que lo creo.

Ya está todo listo para conquistar al mundo!!!!!!!!

Parte 6

sábado, 5 de julio de 2008

El patrón "Observer" (Observador) - Parte IV

Esta desencadenado!!!!! El primer ataque ha sido lanzado. Cerebro ha dado las órdenes a sus tropas para dominar el mundo.

En los ejemplos anteriores hemos visto como Cerebro ha conseguido clonar cualquier robot utilizando un “Patron Prototype”, ha conseguido darles un rol dinámicamente con el “Patron Extension Objects”, y ha repartido las ordenes con un “Patron command”.

Pero como ya sabemos, Cerebro está loco, pero no es tonto. Sabe, que algo puede salir mal, que un pequeño detalle puede destruir sus planes de dominar el mundo. Pero también sabe que una retirada a tiempo es una victoria.

Por lo tanto, ha equipado a sus tropas de una radio de comunicaciones. Pero, porque ha hecho esto?. Sencillo, en el fragor de la batalla, las comunicaciones directas se hacen complicadas. Es difícil hacer llegar las ordenes, y muchas veces no se tiene claro a quien le estamos dando esas órdenes ( será a “Mazinger Z” o “El Vengador”? ). Conquistar el mundo no es fácil, de hecho muchos lo han intentado pero no lo han conseguido.

Cerebro ha estudiado con detenimiento todos los intentos anteriores para no reproducir los mismos errores que otros han cometido. Qué pasaría si para dar nuevas órdenes, necesitase que el sargento “Mazinger Z” tuviese que recorrer la trinchera indicando uno por uno a todos los robots que se retirasen?. Desde que le diese la orden al primer robot, hasta que se la diese al último, pasaría un tiempo precioso. Además, y si ocurre algo por el camino?. Las posibilidades de que las órdenes no lleguen a todos los integrantes de la tropa son amplias.

Sabiendo esto, Cerebro recurre nuevamente a su gurú “Marin Fowler” y decide hacer un cambio fácil y rápido el comportamiento de sus tropas, utilizando el “Patron Observer”.



Como Cerebro no es tonto, ha encontrado una malvada forma de enviar las órdenes a sus tropas. Los robots “Mazinger Z” y “El Vengador”, estarán equipados con una radio que sintoniza “La señal del mal”. Sus tropas estarán atentas a la radio, y cuando esta emita una canción de “Metallica” les indicara que acción deben tomar.

El código sería algo así:















De este modo, Cerebro se puede comunicar rápidamente con todas sus tropas. Es brillante, es genial, es maravilloso, es.........perfecto?. Bueno, la verdad es que está muy bien, pero imaginemos por un momento, una situación en la que un robot consigue infiltrarse en el alto mando enemigo, y descubre que el enemigo está a punto de ser derrotado, y justo en ese momento de éxtasis, la radio emite “The Call of Ktulu" (la canción que indica a las tropas que hay que retirarse).

NOOOOOOOOO (bueno, esto está traducido, claramente, un robot diría algo así como BEP-BEP-BEP). Nuestro robot espía, tiene una información valiosísima, pero que no puede comunicar a su alto mando, porque la forma de transmisión es únicamente de tipo “Push” (desde Cerebro a sus tropas), por lo que no hay retorno.

Qué situación, el robot necesita transmitir que el ataque debe continuar pero......jajajajajajajaja, Cerebro ha pensado en ello, y ha decidido implementar un “Patron observer” que permita la transmisión tipo “Push” (del sujeto emisor a todos los sujetos receptores) y tipo “Pull” (uno de los objetos receptores, puede solicitar una información al objeto emisor para que este la envié a todos los demás). Así, nuestro robot espía, estará equipado con un número de teléfono al que podrá llamar y solicitar que emitan "Master of Puppets", y cuando esta canción sea emitida por la radio, los robots “Mazinger Z” y “El Vengador” que la escuchen, sabrán que ha llegado el momento de la ofensiva final!!!. Para ello, Cerebro deberá modificar ligeramente su código.

El primer paso será que nuestro sujeto, implementara un nuevo método que hemos añadido a la interfaz Sujeto( solicitarInformacion ), que permitirá recibir las llamadas telefónicas del robot espía. Veremos también que el constructor de los robots “Mazinger Z” y “El Vengador” también ha cambiado un poco. Ahora estos robots, almacenaran una referencia al constructor. También modificaremos el código de nuestro robot “Mazinger Z” (suponemos que este será el robot espía en el momento en que decide que pese a lo que emite la radio, hay que atacar y pide que se emita “Master of Puppets” que es otra señal de ataque ).

El código final sería algo así:











Evidentemente, Cerebro que ha estudiado la API de JAVA y sabe que existe la clase java.util.Observable y la interface java.util.Observer. La primera no la ha utilizado, pues eso implicaría que Cerebro extienda o herede de “Observable”. Esto podría ser posible, pero en realidad Cerebro extiende de una larga extirpe de profesores diabólicos empeñados en conquistar el mundo, y ni quiere ni puede extender de Observable. ( class Cerebro extends ExtirpeDeProfesoresDiabolicos, Observable --> esto no es posible ). Por eso ha decidido construirse su propia interface “Sujeto”.

Con respecto a la interface java.util.Observer, si la podría haber utilizado para que sus robots “Mazinger Z” y “El Vengador” la implementasen en lugar de implementar “Observador”, pero ya saben, los genios del mal les gusta hacer las cosas a su manera.

Esta historia continuara……

PARTE 5

jueves, 3 de julio de 2008

El patrón "Command" - Parte III

Todo está preparado. Cerebro ya cuenta con un gran número de copias de los robots “Mazinger Z” y “El Vengador”. Además, ha asignado los roles a cada uno de estos. Es el momento perfecto para que Cerebro lance su ataque final. Ha llegado el momento de conquistar el mundo!!!!

Pero como dará Cerebro la orden de atacar a sus tropas?.

Cerebro está loco, pero no es idiota. Quiere conquistar el mundo, para lo cual ha ideado un plan malvado perfecto!!!. Pero sabe que tener un buen plan (aunque sea malvado) no es una garantía para el éxito. Necesita un plan de emergencia.

Cerebro quiere que algunos de sus robots soldados participen en el primer (y por tanto, glorioso) ataque. Pero también quiere reservar unos cuantos robots soldados y dejarlos descansando, mientras sus colegas son masacrados en el campo de batalla, para que puedan ser utilizados como refuerzos.

Pero, como podrá hacerlo?. Cerebro es un genio muuuuuy ocupado, por lo tanto el ataque debe poder ser lanzado sin mucha intervención de su parte. Algo tan simple como apretar el botón de "Dominar el Mundo" sería perfecto. Es rápido, es fácil, y Cerebro puede delegar la tarea incluso a Pinky.

Eso sería perfecto, pero para conseguirlo tiene que encontrar la forma de poderle decir a cada robot que es lo que se supone que debe hacer cuando el "glorioso momento del ataque" llegue.
Pero cómo ?. El unico conocimiento que tiene Cerebro de los robots soldados es su interfaz, porque sabe que cada robot soldado implementa la interfaz AccionSoldado.

Resumiendo, lo que en realidad necesita es que algunos robots ejecuten uno de los métodos de AccionSoldado, y otros robots ejecuten uno distinto cuando reciban la orden de atacar.





Tanto la interfaz AccionSoldado como la clase RolSoldado no han cambiado.

Cerebro ha logrado crear diez mil robots soldados, y diez mil robots fabricantes, utilizando dos arrays para almacenar una referencia a todos ellos.

Por tanto, al apretar el botón de "Al ataqueeeeeeeeeeeeeee" podría hacer algo así…..



Cerebro está loco, pero no es un tonto. No le gusta la solución que ha encontrado. Por que?. Bueno, no es exactamente lo que quería. Cerebro simplemente quiere poder decir "Al ataqueeeeeeeee", y comenzar a reírse histéricamente mientras los robots se lanzan ciegamente a cumplir sus órdenes.

Cerebro sospecha que todo podría ser mucho más fácil si pudiera darle a cada uno de los robots un sobre conteniendo sus órdenes. Cuando el "Momento de gloria" llegue, simplemente le tendría que decirle a cada robot que habrá el sobre y obedezca las ordenes contenidas en el. Pero él no quiere saber de qué forma tienen que cumplir esas órdenes los robots, de hecho, ni siquiera quiere saber si le está mandando algo a un robot “Mazinger Z” o “El Vengador”, o a lo que sea.

Pero justo en ese momento, comienza a reírse con más fuerza que nunca. Porque ha recordado el patrón Command.



Cerebro quiere dar cuatro órdenes diferentes. Dos para ser obedecidas por los robots soldado ("ataca", y "espera hasta recibir nuevas órdenes"), y las otras dos dirigidas a los robots fabricantes ( "comienza a construir la fortaleza", y "diseña armas" ).

Para esto, va a encapsular la orden y el receptor de dicha orden, en un paquete ( el sobre ). Cómo?....

En primer lugar, escribirá la siguiente interfaz:



Y los distintos comandos serán…..











Por tanto, cuando Cerebro presione el botón de "al ataqueeeeeeeeee", tendrá que hacer un método algo así:



Este método recibe como parámetro un array conteniendo todos los comandos. Ese array se podría construir con un código similar a este…..



El código es horrible, pero sirve para ilustrar como Cerebro ha creado una colección de objetos, cada uno de los cuales encapsula un comando y el receptor de dicho comando.

Ahora, Cerebro no necesita saber nada acerca de esos comandos, ni del receptor de los mismos. Simplemente tiene que decir "ejecutar el comando!!", y el comando hará el resto.

De hecho, Cerebro ha conseguido desacoplar tres procesos diferentes: la creación de los objetos (implementando el patrón Prototype ), la asignación de roles a esos objetos ( con el patrón Extension Objects ), y la forma en que esos roles pasan a la acción ( el patron Command ).

Con esto, ha dado un paso más en su malvado plan de CONQUISTAR AL MUNDO!!!!!

PARTE 4