一、定义
使用共享对象可有效地支持大量的细粒度的对象。
二、使用场景
系统中存在大量的相似对象,或需要缓冲池的场景。
三、UML类图
Flyweight:享元对象抽象基类或者接口。
ConcreteFlyweight:具体享元子类。
UnsharedConcreteFlyweight:不需要共享的享元子类。
FlyweightFactory:享元工厂,负责创建并管理享元对象。
四、实现
//抽象享元类
public abstract class Flyweight {
public abstract void operation(int extrinsicstate);
}
//具体享元子类
public class ConcreteFlyweight extends Flyweight {
@Override
public void operation(int extrinsicstate) {
System.out.println("具体享元子类: " + extrinsicstate);
}
}
//不需要共享的享元子类
public class UnsharedConcreteFlyweight extends Flyweight {
@Override
public void operation(int extrinsicstate) {
System.out.println("不需要共享的享元子类: " + extrinsicstate);
}
}
//享元工厂
public class FlyweightFactory {
private Hashtable flyweights = new Hashtable();
public FlyweightFactory() {
flyweights.add("X", new ConcreteFlyweight());
flyweights.add("Y", new ConcreteFlyweight());
flyweights.add("Z", new ConcreteFlyweight());
}
public Flyweight getFlyweight(String key) {
return (Flyweight)flyweights.get(key);
}
}
//客户端
public class Client {
public static void main(String[] args) {
int extrinsicstate = 22;
FlyweightFactory f = new FlyweightFactory();
Flyweight fx = f.getFlyweight("X");
fx.operation(--extrinsicstate );
Flyweight fy = f.getFlyweight("Y");
fy.operation(--extrinsicstate );
Flyweight fz = f.getFlyweight("Z");
fz.operation(--extrinsicstate );
Flyweight uf = new UnsharedConcreteFlyweight();
uf.operation(--extrinsicstate);
}
}
五、应用
例子:Android Message
Message通过在内部构建一个链表来维护一个被回收的Message对象的对象池,当用户调用obtain方法时会优先从池中取,如果池中没有可以复用的对象则创建一个新的Message对象。这些新创建的Message对象在被使用完之后会被回收到这个对象池中,当下次再调用obtain方法时,它们就会被复用。
六、总结
享元模式可以大大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能,但它同时也提高了系统的复杂性,需要分离出外部状态和内部状态,而且外部状态具有固化特性,不应该随内部状态改变而改变,否则将导致系统的逻辑混乱。