享元模式:使用共享来避免许多相同对象的内存开销。
类图:
包括三个角色:
抽象享元角色(FlyWeight):给出抽象类或者抽象接口,规定具体享元类的实现方法。
具体享元角色(Concrete):实现抽象享元角色,如果有内蕴状态,给出存储空间。
享元工厂角色(FlyWeightFactory):负责管理与创建享元角色。在客户端调用享元对象时,如果系统中存在符合要求的享元对象,就会返回给这个已有的享元对象,如果系统中不存在符合要求的享元对象,那么就会创建一个享元对象,然后提供。
例子如下:
抽象享元角色 AbstractWell类
package flyWeight;
/**
* 抽象享元角色
* 水井的抽象类
* @author wang
*
*/
public abstract class WellAbstract {
public abstract void drawWater();
}
具体享元角色 Well类
package flyWeight;
/**
* 具体享元角色
* 水井的具体类,可以从水井取水
* @author wang
*
*/
public class Well extends WellAbstract{
private String name;
public Well(String name){
this.name = name;
}
public void drawWater(){
System.out.println("从"+name+"水井取水");
}
}
享元工厂角色 FlyWeightFactory类
package flyWeight;
import java.util.Hashtable;
/**
* 享元工厂角色
* 村里的打井队,负责全村的打井工作
* @author wang
*
*/
public class WellTeam {
private Hashtable wells = new Hashtable();
public WellTeam(){}
public Well getWell(Object obj){
Well well = (Well)wells.get(obj);
if(well == null){
well = new Well((String)obj);
wells.put(obj,well);
}
return well;
}
public int getWellSize(){
return wells.size();
}
}
客户端调用 Village类
package flyWeight;
/**
* 调用享元模式,
* 山上有个寺庙 还有个电视转播站,两者都像村委会申请打井
* 村委会下令打井队在山上打井,此时打井队只要打一口井就能满足两者的需求,
* 寺庙与电视转播站只需要一口井就可以了
*
* @author wang
*
*/
public class Village {
WellTeam wellTeam = new WellTeam();
Well wella;
Well wellb;
public Village(){
//寺庙的井
wella = wellTeam.getWell("在山上打口井");
//电视转播站的井
wellb = wellTeam.getWell("在山上打口井");
}
public void drawWater(){
//寺庙取水
wella.drawWater();
//电视转播站取水
wellb.drawWater();
int objSize = wellTeam.getWellSize();
System.out.println("总共打了"+objSize+"口井");
}
public static void main(String args[]){
Village village = new Village();
village.drawWater();
}
}
测试结果如下:
在java中,享元模式最常用的包括java常量池与数据库连接池。