Flyweight (patrón de diseño)

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).

Problema que soluciona 

Tenemos una serie de objetos que contienen entre sus datos información que es idéntica y redundante (hablando en lógica de negocio). Si toda esa información redundante la contenemos sobre uno o varios elementos comunes y que estos sean referenciados por la serie de objetos iniciales conseguimos las siguientes mejoras:
 Disminución del uso de recursos: el uso de referencias (punteros) suele ser más óptimo que cada objeto tenga la información repetida en su interior.
 Protección ante el cambio: al meter toda la información redundante en un elemento común, un cambio en dicha información hace que solo tengamos que tocar un único punto y no distribuir ese cambio en la información redundante en toda la serie de objetos, siendo esto último mucho más propenso a error.

Un ejemplo sería: 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 PelotaFlyweight, que contendrá la información común (radio y color) y otra clase PelotaConcreta, que contendrá las coordenadas concretas de cada pelota y una referencia a un objeto de tipo PelotaFlyweight.

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

En este caso solamente tendríamos una instancia de PelotaFlyweight, 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 PelotaConcreta con determinadas características (mismo radio y color que el solicitado), compruebe si ya existe un PelotaFlyweight 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 PelotaFlyweight existentes.

Pasos para aplicar el patrón 
 Comprobar que el rendimiento en los objetos es un tema primordial, y si el cliente está dispuesto a asumir el reajuste.
 Dividir 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).
 Retirar los elementos con estado extrínseco de los atributos de la clase, y añádale más bien una llamada a métodos.
 Crear una fábrica que pueda almacenar y reutilizar las instancias existentes de clases.
 El cliente debe usar la fábrica en vez de utilizar el operador new si requiere de creación de objetos.
 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úsquedas

Enlaces externos
Página de patrones de diseño (en Inglés)

Patrones de diseño