享元的定义:
享元模式英文称为“Flyweight Pattern”,如果翻译成为羽量级模式,估计会让人有点捉摸不透,而享元,则可以较好的体现该模式的用途,共享元素
享元的用途:
我们知道,在java应用中,会出现许多String a="123",String b="123"之类的String类型的变量,如果只是小应用,到还好,假设是一个庞大的系统,
有好多处都需要用定义String a="223",那开销可想而知,而JDK的开发者自然想到了这点,采用了享元模式解决创建大量相同String变量带来的
开销问题
1 String s1 = "a"; 2 String s2 = "a"; 3 System.out.println(s1 == s2);// String 也是采用享元模式 存储在常量池
执行结果:true
到此,我们先简单总结下何种情况下可以考虑使用享元模式
1、一个系统中存在着大量的细粒度对象;
2、这些细粒度对象耗费了大量的内存。
3、这些细粒度对象的状态中的大部分都可以外部化
1 // 接口 2 interface FlyWeight { 3 public void operation(String s); 4 } 5 6 // 具体实现类 7 class ConcreteFlyWeight implements FlyWeight { 8 private String str;// 内蕴状态 9 10 public ConcreteFlyWeight(String str) { 11 12 this.str = str; 13 } 14 15 public void operation(String s) { 16 System.out.println("内蕴变量:" + str); 17 System.out.println("外蕴变量:" + s); 18 } 19 } 20 21 // 享元工厂 22 class FlyWeightFactory { 23 public FlyWeightFactory() { 24 } 25 26 private Hashtable<String, ConcreteFlyWeight> flyWeights = new Hashtable<String, ConcreteFlyWeight>(); 27 28 public ConcreteFlyWeight factory(String str) { 29 30 ConcreteFlyWeight flyWeight; 31 32 flyWeight = flyWeights.get(str); 33 34 if (null == flyWeight) { 35 flyWeight = new ConcreteFlyWeight(str); 36 flyWeights.put(str, flyWeight); 37 38 } 39 return flyWeight; 40 } 41 42 public int getFlyWeightSize() { 43 44 return flyWeights.size(); 45 } 46 }
执行代码
1 FlyWeightFactory factory = new FlyWeightFactory(); 2 FlyWeight flyWeight = factory.factory("a"); 3 FlyWeight flyWeight2 = factory.factory("b"); 4 FlyWeight flyWeight3 = factory.factory("a"); 5 flyWeight.operation("a fly weight"); 6 flyWeight2.operation("b fly weight"); 7 flyWeight3.operation("c fly weight"); 8 System.out.println(flyWeight == flyWeight3); 9 System.out.println(factory.getFlyWeightSize());
执行结果
内蕴变量:a
外蕴变量:a fly weight
内蕴变量:b
外蕴变量:b fly weight
内蕴变量:a
外蕴变量:c fly weight
true
2
结论:本例子享元模式中,享元工厂只有2个对象,外部可以共享他们,并且内蕴变量不会受到影响
整理下模式框架代码
● 抽象享元(Flyweight)角色 :给出一个抽象接口,以规定出所有具体享元角色需要实现的方法。
● 具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定出的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。
● 享元工厂(FlyweightFactory)角色 :本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。
上述说的其实是单纯的享元
回家继续写
《JAVA与模式》之代理模式