结构型模式之享元模式
一.定义
享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。
二、模式结构成员构成
• Flyweight: 抽象享元类
• ConcreteFlyweight: 具体享元类
• UnsharedConcreteFlyweight: 非共享具体享元类
• FlyweightFactory: 享元工厂类
三.代码示例
1 /** 2 * Flyweight 3 * 抽象享元类 4 */ 5 public interface Flyweight { 6 //一个示意性方法,参数state是外蕴状态 7 public void operation(String state); 8 } 9 10 /** 11 * ConcreteFlyweight 12 * 具体享元类 13 */ 14 public class ConcreteFlyweight implements Flyweight { 15 //代表内部状态 16 private Character intrinsicState = null; 17 /** 18 * 构造函数,内蕴状态作为参数传入 19 * @param state 20 */ 21 public ConcreteFlyweight(Character state){ 22 this.intrinsicState = state; 23 } 24 25 26 /** 27 * 外蕴状态作为参数传入方法中,改变方法的行为, 28 * 但是并不改变对象的内蕴状态。 29 */ 30 @Override 31 public void operation(String state) { 32 // TODO Auto-generated method stub 33 System.out.println("Intrinsic State = " + this.intrinsicState); 34 System.out.println("Extrinsic State = " + state); 35 } 36 37 } 38 39 /** 40 * FlyweightFactory 41 * 享元工厂类 42 */ 43 public class FlyweightFactory { 44 private Map<Character,Flyweight> files = new HashMap<Character,Flyweight>(); 45 46 public Flyweight factory(Character state){ 47 //先从缓存中查找对象 48 Flyweight fly = files.get(state); 49 if(fly == null){ 50 //如果对象不存在则创建一个新的Flyweight对象 51 fly = new ConcreteFlyweight(state); 52 //把这个新的Flyweight对象添加到缓存中 53 files.put(state, fly); 54 } 55 return fly; 56 } 57 } 58 59 /** 60 * client 61 */ 62 public class Client { 63 64 public static void main(String[] args) { 65 // TODO Auto-generated method stub 66 FlyweightFactory factory = new FlyweightFactory(); 67 Flyweight fly = factory.factory(new Character('a')); 68 fly.operation("First Call"); 69 70 fly = factory.factory(new Character('b')); 71 fly.operation("Second Call"); 72 73 fly = factory.factory(new Character('a')); 74 fly.operation("Third Call"); 75 } 76 77 }
四.优点和缺点分析
优点:
>享元模式的优点在于它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份
>享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享
缺点:
>享元模式使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化
>为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长
五.应用场景
>当系统有大量相同或者相似的对象,由于这类对象的大量使用,造成内存的大量耗费
>对象的大部分状态都可以外部化,可以将这些外部状态传入对象中
>使用享元模式需要维护一个存储享元对象的享元池,而这需要耗费资源,因此,应当在多次重复使用享元对象时才值得使用享元模式
你投入得越多,就能得到越多得价值