Busqueda local

Loading

martes, 15 de marzo de 2011

Prototype Pattern

En los últimos post, he presentado ejemplos usando patrones creacionales, aun que son similares, cada uno tiene una razón diferente por la cual existe. Nuestro invitado de hoy es mi tercera alternativa para volver al mismo problema de crear páginas web. En esta ocasión el patrón Prototype, nos ofrece una aproximación diferente, donde el objetivo es evitarnos el proceso de crear la nueva instancia, ya que se emplea una sola instancia del objeto, a manera de prototipo, y a esta instancia se le realiza la clonación, y con algunos cambios, tendremos un nuevo objeto.
 

Acerca de cómo clonar objetos

Como vimos en el post donde hablo de clonar objetos, se debe tener cuidado con los tipos de dato de referencia ya que estos podrían ocasionar que nuestro código fuera incorrecto. Los ejemplos que encontré en internet, usan la clonación superficial, con clases cuyas propiedades todas son de valor; esto les permite hacer la creación del prototipo con mucha más velocidad que si tuviera que ser una copia profunda. Pero en la vida real las clases son más complejas que solo propiedades de valor.
Con respecto al uso de la interface ICloneable hay dos puntos que debemos considerar. La interface se limita a establecer un único método llamado Clone, el cual no nos da ninguna información de cómo se realizo la clonación, no sabemos si fue Superficial o profunda. Además cuando llamamos este método siempre nos devuelve un Objeto genérico, por lo que es necesario realizar el Cast apropiado por nuestra parte.
En el post de Clonar objetos, me centre en presentar un ejemplo práctico, de cómo hacer una copia profunda de un objeto que contenía una colección de otros objetos, como uno de sus miembros. Hice la aclaración con respecto a que el método empleado no era el más simple, y comente que podría haber otros por ahí, aun que no dije nada al respecto.
Las formas de hacer la copia, o sea el código para implementar el método Clone, pueden ser muy diversas.

Algunas formas:

  • Manualmente: Nosotros escribimos el código para realizar la copia del objeto creando la instancia y copiando los valores.
  • MemberwiseClone: Usando el método que nos ofrece el .NET teniendo en cuenta las limitaciones.
  • Reflection: Para nada recomendable, sobre todo por el consumo de recursos, pero si no hay de otra forma, es posible.
  • Serialización: Puede ser incluso más lento que el de Reflection, y se debe tener en cuenta que los Miembros privados, pueden no ser serializados como se desea; además si alguno de los miembros es una Clase, esta debe estar marcada para poder serializarse. La ventaja es que no es necesario hacer modificaciones al código que serializa para hacer la copia, si hay cambios en las clases involucradas.
En algún lugar leí que hay otras sin embargo no recuerdo donde fue, ni he usado algún otro método, así que me limitare a estas formas.
Los requerimientos ya fueron expuestos en el post del Factory y en el del Builder, así que no los voy a repetir, solo les diré que crearemos páginas web para un mecanismo coordinador.
 

Implementando el Patrón

En realidad no usare solo el patrón Prototype, me apoyare en el patrón Singleton, para garantizar que nuestra instancia a usar como prototipo sea única.
Lo interesante es la combinación entre un patrón que garantiza que solo se cree una instancia de una clase y un patrón que realiza copias de dicha instancia para asegurarnos que no sea la misma.
Mano a la obra
El código de la clase pagina que usamos en el ejemplo del Builder, así como las clases relacionadas deben estar marcadas como serializables, esto se hace colocándoles una propiedad entre corchetes:
proto1
proto2
Y así sucesivamente hasta aplicárselo a todas las clases abstractas que creamos para el Builder.
Primero implementaremos el patrón Singleton:
proto3
En el código debemos notar el constructor privado, las variables privadas y estáticas para la instancia de la página y para nuestro objeto de hilo seguro, así como el uso de una propiedad de solo lectura llamada Instancia.
Para el método de clonación les presentare dos formas de implementarlo, la primera es mediante el uso de la interface ICloneable:
proto4
y el segundo mediante un método genérico:
proto5
Para nuestro ejemplo usaremos el Genérico, o sea el segundo.
Ahora crearemos la clase que implementa la creación de la página a partir de un prototipo:
proto
En este ejemplo use un id el cual serviría a la clase para obtener la información de cómo se debe configurar de la base de datos, sin embargo para simplificar el ejemplo, use un Switch, donde simulo los tres diferentes casos; en un ejemplo de la vida real, esto no sería lo apropiado.
Y por último el código de nuestra consola para probar:
proto6
El cual no da como resultado:
proto7
El poder del código solo es completo, si tenemos el conocimiento de como usarlo.

No hay comentarios:

Publicar un comentario