图1
参与者:
Flyweight:描述一个接口,通过这个接口flyweight可以接受并作用于外部状态。
ConcreteFlyweight(MyImage):实现flyweight接口,并为内部状态增加存储空间。ConcreteFlyweight对象必须是可以共享的,它所存储的状态必须是内部的。即:它必须独立于ConcreteFlyweight对象的场景.
UnsharedConcreteFlyweight:并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享,在Flyweight对象结构的某些层次,UnsharedConcreteFlyweight 对象通常将ConcreteFlyweight对象作为子节点。
FlyweightFactory(MyImageFactory):创建并管理Flyweight对象。确保合理的共享Flyweight。当用户请求一个flyweight时,FlyweightFactory对象提供一个已经创建的实例或者创建一个。
Client:维持一个对Flyweight的引用。计算或者存储一个(多个)flyweight的外部状态。Flyweight执行时所需要的状态必定是内部的或者外部的状态,内部状态存储于ConcreteFlyweight对象中,而外部对象则由Client对象存储或计算,当用户调用flyweight对象的操作时,将该状态传递给他。用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight对象,这可以保证对他们适当的进行共享。
本人认为Flyweight模式的核心就是把大量共享的对象收集在一起使用简单工厂模式进行管理,避免由于大量的小对象导致系统的内存过渡消耗。下面是一个简单的例子,例子不是很好,并不能显示Flyweight模式的所有特征。
客户端需要图片,从MyImageFactory中取得,如果MyImageFactory存储的Image中没有需要的图片,便创建一个,并把创建的图片存储在保留Flyweight的数组中,以便于下次直接获取。
相应的代码:
MyImage的代码:
package flyweight;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
public class MyImage{
private Image image;
public MyImage(String file){
Toolkit toolkit = Toolkit.getDefaultToolkit();
File f = new File(file);
if(f.exists()){
image = toolkit.getImage(file);
}
else{
System.out.println("File unable to load!");
}
}
public void draw(Graphics g,int x,int y,String name,ImageObserver obs){
g.drawImage(image,x,y,30,30,obs);
g.drawString(name,x,y+40);
}
}
MyImageFactory的代码:
package flyweight;
public class MyImageFactory{
MyImage[] images;
public MyImageFactory(){
images = new MyImage[3];
for(int i=0;i<3;i++)
images[i]= new MyImage("flyweight/lili"+i+".gif");
}
public MyImage getMyImage(int i){
return images[i];
}
}
Client代码:
package flyweight;
import javax.swing.*;
import java.awt.*;
public class Client extends JFrame{
private MyImageFactory factory;
private String[] names;
public Client(){
super("Flyweight sample");
factory = new MyImageFactory();
setSize(220,300);
setVisible(true);
repaint();
names = new String[]{"pig","dog","cat"};
}
public void resize(){
repaint();
}
public void paint(Graphics g){
g.clearRect(0,0,getWidth(),getHeight());
String name;
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
int number=(int)(Math.random()*3%3);
MyImage myImage = factory.getMyImage(number);
number=(int)(Math.random()*3%3);
name = names[number];
myImage.draw(g,10+i*40,45+j*45,name,this);
}
}
}
public static void main(String[] args){
new Client();
}
}
总结:Flyweight的目标是尽量减少大量可以被共享的对象的数目,并把可变的与不可变得状态使用内部状态(Flyweight)与外部状态区分开来。
本文出自 “凌辉” 博客,请务必保留此出处http://tianli.blog.51cto.com/190322/37118