享元模式以共享的方式高效的支持大量的细粒度对象
享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External State)
一个内蕴状态是存储在享元对象内部的,并且是不会随着环境改变而有所不同
一个外蕴状态是随环境改变而改变的、不可以共享的状态。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入享元对象内部
外蕴状态不可以影响享元对象的内蕴状态,他们是相互独立的
public abstract class Flyweight {
/**一个示意方法,参数state是外蕴状态*/
public abstract void operation(String state);
}
public class ConcreateFlyweight extends Flyweight {
private Character intrinsicState = null;
/**构造器,内蕴状态作为参数传入*/
public ConcreateFlyweight(Character intrinsicState){
this.intrinsicState = intrinsicState;
}
/**
* 外蕴状态作为参数传入方法中,改变方法的行为,但是并不改变对象的内蕴状态
*/
@Override
public void operation(String extrinsic) {
System.out.println("{[intrinsic state:" + intrinsicState + "],[" + "extrinsic state:" + extrinsic + "]}");
}
}
public class FlyweightFactory {
private static FlyweightFactory instance = new FlyweightFactory();
private HashMap<Character,Flyweight> flies = new HashMap<Character,Flyweight>();
@SuppressWarnings("unused")
private Flyweight lnkFlyweight;
private FlyweightFactory(){
}
public static FlyweightFactory getInstance(){
return instance;
}
/**内蕴状态作为参数传入*/
public Flyweight factory(Character intrinsic){
if(flies.containsKey(intrinsic)){
return flies.get(intrinsic);
}else{
Flyweight fly = new ConcreateFlyweight(intrinsic);
flies.put(intrinsic, fly);
return fly;
}
}
public void checkFlyweight(){
int i = 0;
for(Character c : flies.keySet()){
System.out.println("Item:" + (++i) + flies.get(c));
}
}
}
public class Client {
public static void main(String[] args) {
// 创建享元工厂对象
FlyweightFactory factory = FlyweightFactory.getInstance();
// 向享元工厂对象请求一个内蕴状态为'a'的享元对象
Flyweight fly = factory.factory(new Character('a'));
// 传入一个外蕴状态
fly.operation("First Call");
// 向享元工厂对象请求一个内蕴状态为 'b'的享元对象
fly = factory.factory(new Character('b'));
// 传入一个外蕴状态
fly.operation("Second Call");
// 向享元工厂对象请求一个内蕴状态为'a'的享元对象
fly = factory.factory(new Character('a'));
// 传入一个外蕴状态
fly.operation("Thrid Call");
// 向享元工厂对象请求一个内蕴状态为'c'的享元对象
fly = factory.factory(new Character('c'));
// 传入一个外蕴状态
fly.operation("Fourth Call");
// 查看享元工厂
factory.checkFlyweight();
}
}