享元模式是对象的结构模式。
享元模式以共享的方式高效的支持大量的细粒度对象。
享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External)。
一个内蕴状态是存储在享元对象内部的,并且是不会随环境改变而有所不同的。因此,一个享元可以具有内蕴状态并可以共享。
一个外蕴状态是随环境改变而改变的、不可以共享的状态。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入享元对象内部。
外蕴状态不可以影响享元对象的内蕴状态。也就是说,它们是相互独立的。
享元模式的种类
角色如下:
示意源码
抽象享元角色 Flyweight
public abstract class Flyweight {
//一个示意性方法,参数state是外蕴状态
public abstract void operation(String state);
}
具体享元角色 ConcreteFlyweight
public class ConcreteFlyweight extends Flyweight {
private Character intrinsicState = null;
/**
* 构造函数,内蕴状态作为参量传入
* @param state
*/
public ConcreteFlyweight(Character state){
this.intrinsicState = state;
}
/**
* 外蕴状态作为参量传入方法中,改变方法的行为,
* 但是并不改变对象的内蕴状态
*/
@Override
public void operation(String state) {
// TODO Auto-generated method stub
System.out.println("\nInstrinsic State = "+intrinsicState + ".Extrinsic State = "+state);
}
}
享元工厂角色 FlyweightFactory
public class FlyweightFactory {
private HashMap flies = new HashMap();
private Flyweight InkFlyweight;
public FlyweightFactory(){}
public Flyweight factory(Character state){
if(flies.containsKey(state)){
return (Flyweight)flies.get(state);
}else{
Flyweight fly = new ConcreteFlyweight(state);
flies.put(state, fly);
return fly;
}
}
/**
* 辅助方法
*/
public void checkFlyweight(){
Flyweight fly;
int i =0;
System.out.println("\n====checkFlyweight()=====");
for(Iterator it = flies.entrySet().iterator();it.hasNext();){
Map.Entry e = (Map.Entry)it.next();
System.out.println("Item "+ (++i)+":"+e.getKey());
}
System.out.println("======checkFlyweight()======");
}
}
客户端调用
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建一个享元工厂对象
FlyweightFactory factory = new FlyweightFactory();
//向享元工厂对象请求一个内蕴状态为‘a’的享元对象
Flyweight fly = factory.factory(new Character('a'));
//以参量方式传入一个外蕴状态
fly.operation("First Call");
//向享元工厂对象请求一个内蕴状态为‘b’的享元对象
fly = factory.factory(new Character('b'));
//以参量方式传入一个外蕴状态
fly.operation("Second Call");
fly = factory.factory(new Character('a'));
fly.operation("Third Call");
factory.checkFlyweight();
}
}
虽然上面申请了三个享元对象,但是实际上创建的享元对象只有两个,这就是共享的含义。