享元模式
FlyWeight在拳击比赛中中指的是最轻量级,即“蝇量级”或“雨量级”,这里选择使用享元模式的意译,是因为这样更能反映模式的用意。享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象 –《Java与模式》
Java中的String类型
在Java语言中的String类型就是使用的就是享元模式,在Java中的String是作为一个final类型,一旦一个String对象被创建,那么就无法被改变,同时作为一个相同的字符串而言,他们在内存中是共享的(也就是他们是同一地址值)。
public class JavaStringFlyweight { public static void main(String[] args) { String a = "abc"; String b = "abc"; System.out.println(a == b); } }
单纯享元模式
这里主要涉及到的角色有三个Flyweight(抽象享元角色),ConcreteFlyweight(具体享元角色)和FlyweightFactory(享元角色工厂);当然作为单纯享元模式来说,他的所有享元对象是可以共享的。
- 抽象享元角色:主要负责定义享元角色抽象的方法
- 具体享元角色:实现抽象享元角色所定义的方法
- 享元角色工厂:该工厂主要是负责创建,管理具体享元角色;所谓创建,管理来说,也就是在客户端获取某一个具体的享元对象,假如享元工厂中没有改享元对象,那么就创建并保存,假如享元工厂中已经存在改享元对象时,那么直接获取之前的享元对象。
public interface SingleFlyweight { void operation(String s); } public class SingleConcreteFlyweight implements SingleFlyweight { private String instrinsicState = null; public SingleConcreteFlyweight(String instrinsicState) { super(); this.instrinsicState = instrinsicState; } @Override public void operation(String s) { System.out.println("内部享元状态:" + instrinsicState); System.out.println("外部传递参数:" + s); } } public class SingleFlyweightFactory { private Map<String, SingleFlyweight> map = new HashMap<String, SingleFlyweight>(); public SingleFlyweight createFlyweight(String s) { /**首先获取缓存中的享元对象*/ SingleFlyweight singleFlyweight = map.get(s); if (singleFlyweight == null) { /**假如缓存中的享元对象时不存在,那么就创建一个具体的享元对象,并且放入缓存中*/ singleFlyweight = new SingleConcreteFlyweight(s); map.put(s, singleFlyweight); } return singleFlyweight; } } public class Test { public static void main(String[] args) { SingleFlyweightFactory singleFlyweightFactory = new SingleFlyweightFactory(); SingleFlyweight singleFlyweight1 = singleFlyweightFactory.createFlyweight("a"); singleFlyweight1.operation("1"); SingleFlyweight singleFlyweight2 = singleFlyweightFactory.createFlyweight("b"); singleFlyweight2.operation("2"); SingleFlyweight singleFlyweight3 = singleFlyweightFactory.createFlyweight("a"); singleFlyweight3.operation("3"); } }
复合享元模式
相比较与与单纯享元模式,复合享元模式是作为单纯享元对象一个复合存在,作为一个复合享元对象是不可以被共享的,但是作为复合享元对象的组成元素(单纯享元对象)是可以共享的。
上图主要涉及到的角色有:
- 抽象享元角色(Flyweight):享元角色的抽象定义,定义了所有具体享元对象需要实现的方法。
- 具体享元对象(ConcreteFlyweight):实现抽象享元角色抽象方法。
- 复合享元对象(ConcreteCompositeFlyweight):复合享元对象是不可以共享的,但是作为组成复合享元对象中的单纯享元对象是可以共享的。
- 享元工厂角色(FlyweightFactory):这里的复合享元模式工厂角色,与单纯享元模式中的功能一致。
public interface Flyweight { void operator(String s); } public class ConcreteFlyweight implements Flyweight { private String instrinsicState = null; public ConcreteFlyweight(String instrinsicState) { super(); this.instrinsicState = instrinsicState; } @Override public void operator(String s) { System.out.println("内部享元状态:" + instrinsicState); System.out.println("外部传递参数:" + s); } } public class ConcreteCompositeFlyweight implements Flyweight { private Map<String, Flyweight> map = new HashMap<String, Flyweight>(); public void add(String key, Flyweight flyweight) { map.put(key, flyweight); } @Override public void operator(String s) { for (Object flyweight : map.keySet()) { Flyweight tempFlyweight = (Flyweight) flyweight; tempFlyweight.operator(s); } } } public class FlyweightFactory { private Map<String, Flyweight> map = new HashMap<String, Flyweight>(); /** * 复合享元模式工厂方法 * @param list * @return */ public Flyweight factory(List<String> list) { ConcreteCompositeFlyweight concreteCompositeFlyweight = new ConcreteCompositeFlyweight(); for (String tempString : list) { concreteCompositeFlyweight.add(tempString, this.factory(tempString)); } return concreteCompositeFlyweight; } /** * 单纯享元模式工厂方法 * @param s * @return */ public Flyweight factory(String s) { Flyweight flyweight = map.get(s); if (flyweight == null) { flyweight = new ConcreteFlyweight(s); map.put(s, flyweight); } return flyweight; } }
上述博客部分内容参考《JAVA与模式》之享元模式