# 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 ó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