El patrón Flyweight
Descripción
El objetivo del patrón Flyweight es compartir de forma eficaz un conjunto de objetos de granularidad fina.
Ejemplo
En el sistema de venta de vehículos, es necesario administrar las opciones que el comprador puede elegir cuando está comprando un nuevo vehículo.
Estas opciones están descritas por la clase OpciónVehículo que contiene varios atributos tales como el nombre, la explicación, un logotipo, el precio estándar, las incompatibilidades con otras opciones, con ciertos modelos, etc.
Por cada vehículo solicitado, es posible asociar una nueva instancia de esta clase. No obstante a menudo existe un gran número de opciones para cada vehículo solicitado, lo cual obliga al sistema a gestionar un conjunto enorme de objetos de pequeño tamaño (de granularidad fina). Este enfoque presenta sin embargo la ventaja de poder almacenar a nivel de opción la información específica a sí misma y al vehículo, como por ejemplo el precio de venta de la opción que puede diferir de un vehículo a otro.
Esta solución se presenta con un pequeño ejemplo en la figura 3-7.1 y es fácil darse cuenta de que es necesario gestionar un gran número de instancias de OpciónVehículo mientras que entre ellas contienen datos idénticos.
Figura 3-7.1 - Ejemplo de ausencia de compartición en objetos de granularidad fina
El patrón Flyweight proporciona una solución a este problema compartiendo las opciones:
-
La compartición...
Estructura
1. Diagrama de clases
La figura 3-7.3 detalla la estructura genérica del patrón.
Figura 3-7.3 - Estructura del patrón Flyweight
2. Participantes
Los participantes del patrón son los siguientes:
-
FábricaFlyweight (FábricaOpción) crea y administra los flyweights. La fábrica se asegura de que los flyweights se comparten gracias al método getFlyweight que devuelve la referencia hacia los flyweights.
-
Flyweight (OpciónVehículo) mantiene el estado intrínseco e implementa los métodos. Estos métodos reciben y determinan a su vez el estado extrínseco de los flyweights.
-
Cliente (VehículoSolicitado) contiene un conjunto de referencias hacia los flyweights que utiliza. El cliente debe a su vez guardar el estado extrínseco de estos flyweights.
3. Colaboraciones
Los clientes no deben crear ellos mismos los flyweights sino utilizar el método getFlyweight de la clase FábricaFlyweight que garantiza que los flyweights se comparten.
Cuando un cliente invoca un método de un flyweight, debe transmitirle su estado extrínseco.
Dominio de aplicación
El dominio de aplicación del patrón Flyweight es la posibilidad de compartir pequeños objetos (pesos mosca). Los criterios de uso son los siguientes:
-
El sistema utiliza un gran número de objetos.
-
El almacenamiento de los objetos es costoso porque existe una gran cantidad de objetos.
-
Existen numerosos conjuntos de objetos que pueden reemplazarse por algunos objetos compartidos una vez que parte de su estado se vuelve extrínseco.
Ejemplo en Java
La clase OpcionVehiculo posee un constructor que permite definir el estado intrínseco de la opción. En este ejemplo, a parte del nombre, los demás atributos toman valores constantes o que están basados directamente en el nombre. Normalmente, estos valores deberían provenir de una base de datos.
El método visualiza recibe el precio de venta como parámetro, que constituye el estado extrínseco.
public class OpcionVehiculo
{
protected String nombre;
protected String descripcion;
protected int precioEstandar;
public OpcionVehiculo(String nombre)
{
this.nombre = nombre;
this.descripcion = "Descripción de " + nombre;
this.precioEstandar = 100;
}
public void visualiza(int precioDeVenta)
{
System.out.println("Opción");
System.out.println("Nombre: " + nombre);
System.out.println(descripcion);
System.out.println("Precio estándar: " + precioEstandar); ...