享元模式
享元模式为了共享对象,这极大地提升了效率和一致性,这里所指的效率是空间的资源。
定义
运用共享技术有效地支持大量细粒度的对象。
使用场景
- 一个应用程序使用了大量的对象。
- 完全由于使用大量的对象,造成很大的存储开销。
- 对象的大多数状态都变为外部状态。
- 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
- 应用程序不依赖于对象标识,由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
结构
实现
Flyweight接口与子类ConcreteFlyweight和UnsharedConcreteFlyweight的实现,ConcreteFlyweight是可共享的,而UnsharedConcreteFlyweight是不可共享的,它常作为ConcreteFlyweight的子节点。
public interface Flyweight {
void operation(String extrinsicState);
}
public class ConcreteFlyweight implements Flyweight{
private String intrinsicState;
public ConcreteFlyweight(String state){
intrinsicState = state;
}
public void operation(String extrinsicState) {
System.out.println("Intrinsic State = " + this.intrinsicState);
System.out.println("Extrinsic State = " + extrinsicState);
}
}
public class UnsharedConcreteFlyweight implements Flyweight {
private Map<String, Flyweight> files = new HashMap<String, Flyweight>();
public void add(String key, Flyweight fly) {
files.put(key, fly);
}
public void operation(String extrinsicState) {
Flyweight fly = null;
for (Object o : files.keySet()) {
fly = files.get(o);
fly.operation(extrinsicState);
}
}
}
FlyweightFactory用于创建和管理Flyweight对象,确保合理地共享Flyweight。
public class FlyweightFactory {
private Map<String,Flyweight> files = new HashMap<String,Flyweight>();
/**
* 复合享元工厂方法
*/
public Flyweight factory(List<String> compositeState){
UnsharedConcreteFlyweight UnsharedConcreteFly = new UnsharedConcreteFlyweight();
for(String state : compositeState){
UnsharedConcreteFly.add(state,this.getFlyweight(state));
}
return UnsharedConcreteFly;
}
/**
* 单纯享元工厂方法
*/
public Flyweight getFlyweight(String state){
//先从缓存中查找对象
Flyweight fly = files.get(state);
if(fly == null){
//如果对象不存在则创建一个新的Flyweight对象
fly = new ConcreteFlyweight(state);
//把这个新的Flyweight对象添加到缓存中
files.put(state, fly);
}
return fly;
}
}
测试代码
public class Client {
public static void main(String[] args) {
List<String> list = new ArrayList<String> ();
list.add("b");
FlyweightFactory flyFactory = new FlyweightFactory();
Flyweight unsharedConcreteFlyweight1 = flyFactory.factory(list);
Flyweight unsharedConcreteFlyweight2 = flyFactory.factory(list);
System.out.println(unsharedConcreteFlyweight1==unsharedConcreteFlyweight2);
Flyweight concreteFlyweight1 = flyFactory.getFlyweight("a");
Flyweight concreteFlyweight2 = flyFactory.getFlyweight("a");
System.out.println(concreteFlyweight1==concreteFlyweight2);
}
}
运行结果:
false
true
由此我们可以了解到享元模式不是强制共享所有的Flyweight对象,当要获得共享对象时不是直接实例化ConcreteFlyweight,而是通过FlyweightFactory 来获得,确保下次要获得的对象时同一个,以此来达到共享的目的,这一应用在数据库连接池中可以体现,有兴趣的朋友可以去了解相关资料,加深理解。