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

lunes, 23 de junio de 2008

Tutorial de Tomcat en Cluster

Lo primero que necesitaremos será descargar el servidor Web Apache para poder hacer el balanceo de carga (Load Balancing) y la compartición de carga (Load Sharing).

Para esto, descargaremos el archivo apache_2.2.9-win32-x86-no_ssl-r2.msi desde aquí. Una vez descargado, procedemos a la instalación.








Ya instalado el servidor Web Apache, deberemos proceder a instalar Tomcat y definir el tipo de cluster a implementar.

Existen dos tipos de cluster que podemos construir en Tomcat: cluster vertical (en una sola maquina) o cluster horizontal (en muchas maquinas).


Cluster vertical

El primer paso será la instalación de Tomcat, para lo que deberemos bajar el archivo apache-tomcat-6.0.9.exe desde aquí.

Una vez descargado el archivo, procederemos instalar Tomcat. Para este ejemplo, vamos a simular que el cluster está compuesto por tres nodos, por lo tanto, necesitaremos instalar tres instancias de Tomcat las cuales llamaremos: TomcatNodo1, TomcatNodo2 y TomcatNodo3.

El paso que realizaremos a continuación deberemos repetirlo para cada nodo.







Una vez instalado los tres nodos, deberemos realizar una pequeña modificación al archivo server.xml de cada uno de los nodos. Este archivo se encuentra en la carpeta "conf" de cada uno de los nodos.

Para cada uno de los server.xml deberemos realizar los siguientes cambios:

Cambiar los puertos



Agregamos el “jvmRoute” para cada caso.



Descomentamos el tag “cluster



Nodo1



Nodo2



Nodo3




Con estos cambios ya tenemos configurado nuestro cluster vertical.


Cluster Horizontal

La configuración de un cluster horizontal es un poco más fácil ya que no es necesario realizar cambios a los puertos.

Para cada uno de los archivos server.xml se debe realizar los siguientes cambios:

Agregamos el “jvmRoute” para cada caso (igual que para el cluster vertical)



Descomentamos el tag “cluster” (igual que para el cluster vertical)




Configuración del cluster con Apache

Una vez configurado el tipo de cluster (Horizontal o Vertical), vamos a construir una pequeña aplicación de ejemplo.

El primer paso será definir en el web.xml de la aplicación el tag <distributable /> para activar el intercambio de la sesión a través de la instancia del cluster.



Ahora necesitaremos integrar el servidor web Apache con Tomcat instalando el modulo mod_jk. Para esto, deberemos descargar el archivo mod_jk-1.2.26-httpd-2.2.4.so desde aquí y dejarlo en la carpeta “modules” de Apache.

Ya instalado el mod_jk, deberemos editar el archivo httpd.conf que está en la carpeta “conf” con las siguientes líneas:



Ahora deberemos crear el archivo workers.properties dentro de la carpeta “conf” del Apache. En este archivo definiremos las propiedades para cada una de las instancias de Tomcat a ejecutar.

En el caso de que nuestro cluster sea vertical, el archivo de propiedades deberá contener lo siguiente:



Para el caso de que el cluster sea horizontal deberemos definir el host para cada uno de los nodos del cluster:



Uno de los atributos más importantes es “Ibfactor”, el cual define el factor para el balanceo de carga, restringiendo el numero de “request” a enviar a una instancia particular de Tomcat.

Por último, crearemos unas páginas JSP para cada uno de los nodos, con los cuales validaremos que el cluster este funcionado correctamente.


TomcatNodo1



TomcatNodo2



TomcatNodo3




Por último, se debe reiniciar el Apache y luego iniciar cada una de las instancias del Tomcat.

Una vez los nodos estén iniciados, ejecutaremos la página cluster.jsp y validaremos el ID de la sesión asignada además del nombre del nodo que atendió la petición.

Recargamos nuevamente la pagina, y validamos que el ID de la sesión siga siendo la misma, con esto, validamos que el cluster este funcionado correctamente.





Si necesitan ajustar mejor la configuración del cluster, les recomiendo el libro “PROFESIONAL APACHE TOMCAT 6”.

sábado, 21 de junio de 2008

El patrón “Extension Objects” - Parte II

En el episodio anterior, Cerebro logro programar una máquina capaz de crear muchas copias de robots, logrando construir un gran ejército para CONQUISTAR AL MUNDO!!!.

Pero de repente, se dio cuenta que va a necesitar muchos robots del tipo “Mazinger Z” y también del tipo “El Vengador”, pero no todos los robots deberían tener el mismo rol. Por qué?. Bueno, dominar el mundo no es fácil. Hace falta organización. Hace falta un malvado plan!.

Entonces Cerebro ideo un plan. Quiere entrenar a algunos de sus robots como soldados para crear maquinas de matar sin misericordia!!!!.

Pero también quiere que otros robots trabajen en las fábricas haciendo armas, y también necesita que otro grupo de robots trabaje en la construcción de una fortaleza…….ufff.

Por lo tanto, se puede decir que necesita poder asignar distintos roles a los robots que ha construido.

Entonces, Cerebro comienza a pensar…….muy bien, ya tengo una clase que representa un robot “Mazinger Z”, pero ahora necesito tener un “Mazinger Z” que se comporte como un soldado, otro que se comporte como un fabricante, otro como constructor y lo mismo para “El Vengador”. Eso suena a "extender la funcionalidad de una clase", o no?....Brillante!!.

Escribiré una clase “MazingerZSoldado” que extienda a “MazingerZ”, y otra clase, “MazingerZFabricante”, que también extienda a “MazingerZ”.

Pero antes de ponerse a escribir código, Cerebro se da cuenta que probablemente esa no sea la mejor solución, porque cada vez que quiera asignar un nuevo rol a una robot, tendrá que escribir una nueva subclase (por ejemplo, una “MazingerZIngeniero”, o una “MazingerZConstructor”).

Además, el no sabe a priori cuantos roles va a necesitar asignar a un robot. Todo depende de lo que necesite en el futuro. Necesita dar soporte a la adición de interfaces desconocidas a la clase “MazingerZ”.

También se da cuenta que su primera forma de atacar el problema tiene otro punto débil, y es que no podrá re-asignar un rol. Si crea un “MazingerZSoldado”, tendrá esta para siempre, aunque la necesite para construir nuevos robots.

Pero también se da cuenta de otro punto débil, este es mucho más sutil. Una clase “MazingerZSoldado” y una “MazingerZ” son exactamente lo mismo. La única diferencia es que una de ellas tiene un comportamiento particular, pero en esencia, son lo mismo. Por tanto, no es muy apropiado representarlas utilizando clases distintas.

Cerebro está loco, pero no es tonto. Por tanto, decide que ha encontrado demasiados puntos débiles para su idea inicial, y que por tanto, es el momento de acudir al patrón “Extension Objects”.

Este patrón intenta anticipar la extensión de la interfaz de un objeto en el futuro (eso quiere decir: se pueden añadir interfaces a una clase en tiempo de ejecución). Así que empieza a leer, y a reírse. Y cuanto más lee, mas se ríe.

La idea es muy sencilla. Una clase (MazingerZ) será capaz de cambiar la interfaz que implementa en tiempo de ejecución, seleccionando esa interfaz de entre una colección de objetos ( los Extension Objects ). Cada uno de esos objetos encapsularan uno de los roles (MazingerZSoldado, MazingerZFabricante,... ).

Pero como será capaz la clase “MazingerZ“ de seleccionar la interfaz a implementar? Y de igual manera la clase “ElVengador”?. Bien, ambas clases implementaran la siguiente interfaz.



La clase “MazingerZ” implementa una interfaz para encapsular las acciones que implementa por ser un robot (mover la cabeza, mover las piernas, los brazos).



















Fíjense como la clase “MazingerZ” implementa el método “getExtension”, que elige la clase que debe devolver de entre una colección de roles (que son variables de la clase). Y los roles ?.

Para ese caso está la clase abstracta Rol (no he implementado nada en el, pero cualquier funcionalidad común a los roles debería implementarse aquí).



Pero Cerebro no es tonto, y sabe que en algún momento necesitara cambiar los roles de sus Robots. En algún momento puede llegar a necesitar que los robots que tienen el rol fabricante deban pasar a tener el rol soldado. Sería posible construir un “MazingerZ” con distintos tipos de roles, y que estos puedan ser modificados en cualquier momento?.

Entonces Cerebro luego de estudiar mejor el patrón “Extension Objects” decide refactorizar su código.







Ahora, los robots construidos por su máquina podrán cambiar su rol en tiempo de ejecución primero pueden ser soldados, luego fabricantes, mas tarde lo que a Cerebro le dé la gana).

Cerebro ha conseguido mantener la abstracción “MazingerZ” limpia de operaciones específicas para un robot. Eso también lo podría haber conseguido gracias a la herencia, definiendo las operaciones para los robots en las subclases, pero eso habría generado una jerarquía difícil de manejar.

Cerebro a dado un paso más en su plan de CONQUISTAR AL MUNDO!!!!!.

PARTE 3