Flyweight
Clasificación
Estructural
Intención
Uso compartido de objetos para soportar un gran número de objetos finos eficientemente.
Motivo
Aplicabilidad
• Una aplicación usa un gran número de objetos.
• El coste de almacenamiento es alto de-bido al excesivo número de objetos.
• La gran mayoría de los estados de los objetos puede hacerse extrínseco.
• Al separar el estado extrínseco, muchos grupos de objetos pueden reemplazarse por unos pocos objetos compartidos.
• La aplicación no depende de la identi-dad de los objetos, pues el patrón se basa en el compartimento de objetos.
Estructura
Participantes
• ConcreteFlyweight: implementa la interfaz Flyweight y almacena estados intrín-secos, si existen. Los ConcreteFlyweight deben ser compartibles, cualquier estado de este debe ser intrínseco.
• UnsharedConcreteFlyweight: No todos los flyweight tienen que ser compartidos, la interfaz Flyweight habilita el comparti-miento pero no lo fuerza. Es común que los objetos UnsharedConcreteFlyweight tengan objetos ConcreteFlyweight como hijos en algún nivel de la estructura del flyweight.
• FlyweightFactory: Crea y maneja objetos flyweight, se asegura que flyweights se-an compartidos adecuadamente. Cuando el cliente hace la petición de flyweight la FlyweightFactory proporciona una ins-tancia existente, y si no existe crea una.
• Client: Mantiene una referencia a Fly-weight. Almacena o calcula los estados extrínsicos de los flyweights.
Colaboración
• Los clientes no deben obtener estados directamente de ConcretFlyweight, sino por medio de FlyweightFactory, quien es que se asegura que los objetos sean compartidos adecuadamente.
Consecuencias
• La reducción del número total de instan-cias que son compartidas.
• La cantidad de estados intrínsecos por objeto.
• Si el estado extrínseco es calculado o almacenado.
Es conveniente que los estados extrínsecos se calculen y no se almacenen, pues esto genera un ahorro extra de memoria.El patrón se suele combinar con composite, para representar la estructura jerárquica co-mo un grafo con nodos y hojas como objetos compartidos.
Implementación
• Eliminar estados extrínsecos. El patrón depende ampliamente de identificar es-tados extrínsecos y removerlos de los objetos compartidos. Los estados extrín-secos, por su parte deben ser calcula-dos, en alguna parte donde los requeri-mientos de memoria sean bajos.
• Debido a que los flyweight son comparti-dos, no deberían ser instanciados direc-tamente por los clientes. La clase Fly-weightFactory deja a los clientes localizar un flyweight en particular.
Código ejemplo
//Interfa Flyweight
import java.awt.Image;
public interface Pelota {
public Image getPelota();
}
//ConcreteFlyweight implementa la inerfaz y guarda estados intrínsecos
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class PelotaConcreta implements Pelota {
private BufferedImage imagen;
public PelotaConcreta() {
try{
imagen= ImageIO.read(getClass().getClassLoader().getResource("pelota.gif"));
}catch(IOException e){
System.out.println("no se puede cargra la imagen");
}
}
public Image getPelota(){
System.out.println("aqui");
return (Image)imagen;
}
}
//(FlyweightFactory) garantiza que los objetos se inicialicen correctamente.
//Fijese que esta clase es un singleton.
public class PelotaFactory {
private static Pelota miPelota =null;
public static Pelota getPelota(){
if(miPelota==null)miPelota=new PelotaConcreta();
return miPelota;
}
}
//(Client) Mantiene una referencia a pelota
//almacen estados esxtrínsecos.
import java.awt.Image;
public class DibujaPelota {
private Pelota pelota = PelotaFactory.getPelota();
//Estados extrínsicos que son mantenidos por el cliente
private int cordX=0;
private int cordY=0;
public Image getPelota(){
return pelota.getPelota();
}
public void setCordX(int x){
cordX=x;
}
public void setCordY(int y){
cordY=y;
}
public int getCordX(){
return cordX;
}
public int getCordY(){
return cordY;
}
}
//clase que se encarga d la presentacion
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Image;
import java.awt.Graphics;
import java.util.Random;
public class Presentacion extends JFrame implements ActionListener{
private final int DIMENSION_IMAGEN =40;
private JPanel panel;
private JButton mover;
private Image imagen=null;
private DibujaPelota pelotas[]={new DibujaPelota(),new DibujaPelota(),new DibujaPelota(),new DibujaPelota(),new DibujaPelota()};
private DibujaPelota pelota=pelotas[0];
private int x=0;
private int y=0;
private Random aleatorio= new Random(1000L);
public Presentacion(){
panel = new JPanel();
mover=new JButton("Mover");
this.setTitle("Pelotas");
this.setSize(350,400);
this.setResizable(false);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel=(JPanel)this.getContentPane();
panel.setLayout(null);
panel.add(mover);
mover.setBounds(20, 20, 70, 20);
mover.addActionListener(this);
//aleatorio.setSeed(1000);
}
public static void main(String args[]){
new Presentacion();
}
public void paint(Graphics g){
g.fill3DRect(100, 100, 20, 20, true);
g.clearRect(x,y+100,DIMENSION_IMAGEN,DIMENSION_IMAGEN);
imagen=pelota.getPelota();
g.drawImage(imagen,pelota.getCordX(),pelota.getCordY(),DIMENSION_IMAGEN,DIMENSION_IMAGEN,this);
}
public void actionPerformed(ActionEvent e) {
for(int i=0; i<5;>
x=pelotas[i].getCordX();
y=pelotas[i].getCordY();
pelotas[i].setCordX((int)aleatorio.nextLong()*240);
pelotas[i].setCordY((int)aleatorio.nextLong()*340);
pelota=pelotas[i];
}
repaint();
}
}
Usos conocidos
• Et++ usa flyweight para soportar diferen-tes apariencias (look and feel).
Patrones relacionados
• Como se menciono anteriormente, Com-posite es combinado con este patrón pa-ra representar las jerarquías de herencia como un árbol con nodos y hojas que hacen el papel de objetos compartidos.
• Comúnmente es conveniente implemen-tar State y Strtegy son immolementados con Flyweight.
Referencias bibliográficas
[1] Erich Gamma et al, Elements of reusable object-oriented software.
[2] Steve Holzner, Design patterns for dummies, Wiley Publishing Inc, Indianapolis, EEUU, 2006, 339.
[3] Jesús García Molina, Análisis y diseño de software - Patrones de diseño, dis.um.es/~jmolina/astema3.
5 comentarios:
buen post...te dejo mi blog http://www.oscar-sandoval.blogspot.com/
ok , gracias, se hace lo que se puede, revisaré tu blog.
no me funcionó el ejemplo. Lo traté de adaptar al netbeans pero tira un error:
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
Hola! Esta muy excelente tu post..es muy interesante..ya ratos andaba en la web buscando una info de los patrones de diseño pero casi no entendia hasta que lei el tuyo..esta excelente!
Saludos
Hola buena info, pero tengo una duda según entiendo es para crear elementos de 'usar y tirar', o sea, que no puedo crear elementos (por ejemplo líneas) y acceder luego a ellos para por ejemplo seleccionarlos haciendo click, ¿es así?
Gracias :)
Publicar un comentario