类图
定义
使用共享对象可有效地支持大量的细粒度的对象
优点
- 大大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能缺点
- 提高了系统的复杂性,需要分离出外部状态和内部状态
使用场景
- 系统中存在大量相似对象
- 细粒度的对象都具备较接近的外部状态,且内部状态与环境无关
- 需要缓冲池的场景
注意事项
外部状态最好以java基本类型(int,string等)作为标志,可以大幅提高效率。
如果把一个对象作为键值,一定要确保重写了equals和hashcode方法。
关于对象池和享元模式的区别,对象池着重在对象的复用上,池中的每个对象是可替换的,
从同一个池中获得A对象和B对象对客户端来说是完全相同的,它主要解决服用,
而享元模式主要解决的是对象的共享问题,如何建立多个可共享的细粒度对象则是其关注的重点
抽象享元角色
public abstract class FlyWeight {
private String intrinsic;
protected final String extrinsic;
public FlyWeight(String _extrinsic) {
this.extrinsic = _extrinsic;
}
/**
* 定义业务操作
*/
public abstract void operate();
// 内部状态的getter和setter
public String getIntrinsic() {
return intrinsic;
}
public void setIntrinsic(String intrinsic) {
this.intrinsic = intrinsic;
}
}
具体享元角色
public class ConcreteFlyWeight extends FlyWeight {
/**
* @param _extrinsic
*/
public ConcreteFlyWeight(String _extrinsic) {
super(_extrinsic);
}
/**
* 根据外部状态进行逻辑处理
*/
@Override
public void operate() {
System.out.println("ConcreteFlyWeight->" + extrinsic);
System.out.println("ConcreteFlyWeight->" + getIntrinsic());
}
}
享元工厂
public class FlyWeightFactory {
private static HashMap<String, FlyWeight> pool = new HashMap<>();
public static FlyWeight getFlyWeight(String extrinsic) {
FlyWeight flyWeight;
if (pool.containsKey(extrinsic)) {
flyWeight = pool.get(extrinsic);
} else {
flyWeight = new ConcreteFlyWeight(extrinsic);
pool.put(extrinsic, flyWeight);
}
return flyWeight;
}
}
场景类
public class Client {
public static void main(String[] args) {
// fw1和fw2共享了同一个对象
FlyWeight fw1 = FlyWeightFactory.getFlyWeight("name 1");
fw1.setIntrinsic("fw1");
fw1.operate();
FlyWeight fw2 = FlyWeightFactory.getFlyWeight("name 1");
fw2.setIntrinsic("fw2");
fw2.operate();
// fw3使用了一个新对象
FlyWeight fw3 = FlyWeightFactory.getFlyWeight("name 3");
fw3.setIntrinsic("fw3");
fw3.operate();
}
}
运行结果
ConcreteFlyWeight->name 1
ConcreteFlyWeight->fw1
ConcreteFlyWeight->name 1
ConcreteFlyWeight->fw2
ConcreteFlyWeight->name 3
ConcreteFlyWeight->fw3