domingo, 27 de octubre de 2013

Patrones Estructurales: Flyweight y Proxy


- Flyweight (Peso ligero): Reduce la redundancia cuando gran cantidad de objetos poseen idéntica información.



     El patrón Flyweight (u objeto ligero) sirve para eliminar o reducir la redundancia cuando tenemos gran cantidad de objetos que contienen información idéntica, además de lograr un equilibrio entre flexibilidad y rendimiento (uso de recursos).




                                                  Representación gráfica del Flyweight.


Problema que soluciona


     Necesitamos representar gráficamente muchas pelotas idénticas que rebotan en los bordes de una ventana, así que creamos una clase que tenga por atributos las coordenadas, el radio y el color con que se dibujará la pelota.



     Problema: Aunque las coordenadas son distintas, como queremos que nuestras pelotas sean iguales, el radio y el color se repetirán en cada instancia, desperdiciando memoria.



Implementación


     Crear una clase Pelota Flyweight, que contendrá la información común (radio y color) y otra clase Pelota Concreta, que contendrá las coordenadas concretas de cada pelota y una referencia a un objeto de tipo Pelota Flyweight.



      Al crearse instancias de PelotaConcreta, se les deberá proveer de referencias a la instancia de Pelota Flyweight adecuada a nuestras necesidades.



     En este caso solamente tendríamos una instancia de Pelota Flyweight, puesto que hemos dicho que todas nuestras pelotas tienen el mismo radio y color, pero pensando en un ejemplo en el que tuviéramos varios grupos de pelotas, y dentro de cada uno de los cuales se compartieran el radio y el color, se puede utilizar Flyweight conjuntamente con el patrón Factory, de tal modo que este último, en el momento en que se le soliciten instancias de Pelota Concreta con determinadas características (mismo radio y color que el solicitado), compruebe si ya existe un Pelota Flyweight con ese radio y color, y devuelva esa referencia o, en caso de que no exista, la cree y la registre. El patrón Factory se encargaría de gestionar los Pelota Flyweight existentes.



Pasos para aplicar el patrón


1. Asegúrese que el rendimiento en los objetos es un tema primordial, y si el cliente está dispuesto a asumir el reajuste



2. Divida el objetivo principal en estados: Estado Intrínseco (elementos que se puedan compartir o son comunes) y Estado Extrínseco (elementos particulares a cada tipo)



3. Retire los elementos con estado extrínseco de los atributos de la clase, y añádale más bien una llamada a métodos



4. Crear una fábrica que pueda almacenar y reutilizar las instancias existentes de clases



5. El cliente debe usar la fábrica en vez de utilizar el operador new si requiere de creación de objetos



6. El cliente (o un tercero) debe revisar los estados extrínsecos, y reemplazar esos estados a métodos de la clase



Ventajas y Desventajas


Ventajas: Reduce en gran cantidad el peso de los datos en un servidor



Desventajas: Consume un poco más de tiempo para realizar las búsqueda

 

   - Proxy: Mantiene un representante de un objeto.



     El patrón Proxy es un patrón estructural que tiene como propósito proporcionar un subrogado o intermediario de un objeto para controlar su acceso.



                                                      Representación gráfica de Proxy

Motivación


     Para explicar la motivación del uso de este patrón veamos un escenario donde su aplicación sería la solución más adecuada al problema planteado. Consideremos un editor que puede incluir objetos gráficos dentro de un documento. Se requiere que la apertura de un documento sea rápida, mientras que la creación de algunos objetos (imágenes de gran tamaño) es cara. En este caso no es necesario crear todos los objetos con imágenes nada más abrir el documento porque no todos los objetos son visibles. Interesa por tanto retrasar el coste de crear e inicializar un objeto hasta que es realmente necesario (por ejemplo, no abrir las imágenes de un documento hasta que no son visibles). La solución que se plantea para ello es la de cargar las imágenes bajo demanda. Pero, ¿cómo cargar las imágenes bajo demanda sin complicar el resto del editor? La respuesta es utilizar un objeto proxy. Dicho objeto se comporta como una imagen normal y es el responsable de cargar la imagen bajo demanda.



Aplicabilidad


     El patrón proxy se usa cuando se necesita una referencia a un objeto más flexible o sofisticado que un puntero. Dependiendo de la función que se desea realizar con dicha referencia podemos distinguir diferentes tipos de proxies:

  • proxy remoto: representante local de un objeto remoto.
  • proxy virtual: crea objetos costosos bajo demanda (como la clase Imagen Proxy en el ejemplo de motivación).
  • proxy de protección: controla el acceso al objeto original proxy de referencia inteligente: sustituto de un puntero que lleva a cabo operaciones adicionales cuando se accede a un objeto (ej. contar número de referencias al objeto real, cargar un objeto persistente bajo demanda en memoria, control de concurrencia de acceso tal como bloquear el objeto para impedir acceso concurrente, …).

  Colaboraciones


      Dependiendo de la clase de proxy, el objeto proxy redirige las peticiones al objeto real que representa.

Ejemplos de funcionamiento:

  • Diagrama de clases para un ejemplo del patrón proxy.
  • Diagrama de secuencia para un ejemplo en el que no se utiliza el patrón proxy.
  • Diagrama de secuencia para un ejemplo en el que se utiliza el patrón proxy.

  Consecuencias


     El uso de un proxy introduce un nivel de indirección adicional con diferentes usos:

  • Un proxy remoto oculta el hecho de que un objeto reside en otro espacio de direcciones.
  • Un proxy virtual puede realizar optimizaciones, como la creación de objetos bajo demanda.
  • El proxy de protección y las referencias inteligentes permiten realizar diversas tareas de mantenimiento adicionales al acceder a un objeto.

     Además, su uso también permite realizar una optimización COW (copy-on-write) , puesto que copiar un objeto grande puede ser costoso, y si la copia no se modifica, no es necesario incurrir en dicho gasto. Además el sujeto mantiene un número de referencias, y sólo cuando se realiza una operación que modifica el objeto, éste se copia. Es útil por tanto para retrasar la replicación de un objeto hasta que cambia.

  Patrones relacionados


  • El patrón Adaptador proporciona una interfaz diferente al objeto que adapta, mientras que el proxy tiene la misma interfaz, pero ambos redirigen la petición del cliente al verdadero sujeto que la ejecuta con la posibilidad de incorporar lógica adicional : comprobación de acceso, creación del sujeto real…

  • El Proxy se puede diseñar de manera similar al patrón decorador, pero el propósito es diferente: el decorador añade responsabilidades a un objeto, el proxy sólo controla su acceso. Así, si el proxy no tiene una fuerte dependencia con el sujeto real (por ejemplo, no es de creación), y no tiene que instanciarlo, puede adoptar el mismo diseño que el decorador, y ser un proxy de cualquier sujeto (referencia a la interfaz que el cliente conoce).

  Ejemplos comunes de la aplicación del patrón proxy


     A continuación se presentan algunos de los ejemplos más comunes en los que se utiliza el patrón proxy:

  • Añadir acceso de seguridad a un objeto existente. El proxy determinará si el cliente puede acceder al objeto de interés (proxy de protección).
  • Proporcionando interfaz de recursos remotos como el servicio web o recursos REST.
  • Coordinación de las operaciones costosas en recursos remotos pidiendo los recursos a distancia para iniciar la operación tan pronto como sea posible antes de acceder a los recursos.
  • Agregar una operación segura para los subprocesos a una clase existente sin cambiar el código de la clase existente.



 




4 comentarios:

  1. Los patrones estructurales y de comportamiento :están enfocados en la gestión de la forma en la que las clases y los objetos se combinan para dar lugar a estructuras más complejas. Al igual que en las otros tipos de patrones, podemos hablar de patrones estructurales asociados a clases (Adapter) y asociados a objetos (Bridge, Composite, Decorator, Facade, Flyweight, Proxy),

    ResponderEliminar
  2. Buen Contenido Marzzia los Patrones Estructurales: Flyweight y Proxy basan su importancia en el uso compartido de objetos para soportar un gran número de objetos finos eficientemente; una de las primeras utilidades que se le dio al patrón fue en un poderoso editor de texto, de inter-views, llamado Doc.

    ResponderEliminar
  3. Por medio de los patrones Flyweight podemos eliminar la redundancia de objetos y así lograr la liberación de memoria para optimizar su rendimiento

    ResponderEliminar
  4. No esta demás comentar que el Patrón estructural Proxy… tiene como propósito proporcionar un intermediario de un objeto para controlar su acceso.

    ResponderEliminar