Este patrón resulta tremendamente útil para evitar crear un gran número de objetos similares, mejorando con ello el rendimiento de la aplicación.
No se trata de crear muchos objetos de forma dinámica, sino de crear sólo un objeto intermedio para cada entidad concreta.
Veamos un ejemplo clásico de uso de este patrón para que nos ayude a comprender cómo implementarlo: la creación de líneas de diferentes colores.
Main.java (Cliente en el diagrama anterior):
package estructurales.flyweight.flyweight01;
public class Main
{
public static void main(String[] args)
{
FabricaDeLineas fabrica = new FabricaDeLineas();
ILineaLigera linea1 = fabrica.getLine( "AZUL" );
ILineaLigera linea2 = fabrica.getLine( "ROJO" );
ILineaLigera linea3 = fabrica.getLine( "AMARILLO" );
ILineaLigera linea4 = fabrica.getLine( "AZUL" );
System.out.println("-------------------");
//can use the lines independently
linea1.dibujar( 100, 400 ) ;
linea2.dibujar( 200, 500 );
linea3.dibujar( 300, 600 );
linea4.dibujar( 400, 700 );
}
}
FabricaDeLineas.java (FabricaDePesosLigeros en el diagrama anterior):
package estructurales.flyweight.flyweight01;
import java.util.ArrayList;
import java.util.List;
public class FabricaDeLineas
{
private List<ILineaLigera> lineas;
// --------------------
public FabricaDeLineas()
{
this.lineas = new ArrayList<ILineaLigera>();
}
// --------------------
public ILineaLigera getLine( String color )
{
// Comprobar si hemos creado una línea con el color solicitado, y devolverla en tal caso
for(ILineaLigera linea : this.lineas)
{
if( linea.getColor().equals(color) )
{
System.out.println("Línea de color [" + color + "] encontrada, la devolvemos");
return linea;
}
}
// Si no ha sido creada la creamos ahora, la agregamos a la lista y la devolvemos
System.out.println("Creando una línea de color [" + color + "]");
ILineaLigera linea = new Linea( color );
this.lineas.add( linea );
return linea;
}
}
ILineaLigera.java (PesoLigero en el diagrama anterior):
package estructurales.flyweight.flyweight01;
public interface ILineaLigera
{
public String getColor();
public void dibujar( int col, int fila );
}
Linea.java (PesoLigeroConcreto en el diagrama anterior):
package estructurales.flyweight.flyweight01;
public class Linea implements ILineaLigera
{
private String color;
// --------------------
public Linea( String color )
{
this.color = color;
}
// --------------------
@Override
public String getColor()
{
return this.color;
}
// --------------------
@Override
public void dibujar( int col, int fila )
{
System.out.println( "Dibujando línea de color [" + this.color + "] en [" + col + ", " + fila + "]" );
}
}
Al ejecutarlo obtendríamos como resultado:
EXPLICACIÓN:
- La clase FabricaDeLineas guardará referencias a objetos ILineaLigera (los cuales son creados una sola vez por cada tipo de línea).
- Así según el ejemplo, cuando se desea dibujar una línea de color azul se crea un objeto ILineaLigera, pero cuando se quiere crear otra similar se accede al objeto ya almacenado en la lista (observa que para ello hace uso del patrón Singleton).
- De este modo si por ejemplo se desean crear mil líneas... no es necesario crear un objeto para cada una de ellas.