设计模式之享元模式

享元模式(FlyWeight),其含义是运用共享技术有效地支持大量细粒度的对象,即系统只使用少许的对象,而这些对象都相近,状态变化很小,对象使用次数却不少。java

享元模式能作到共享的关键是区份内蕴状态和外蕴状态,一个内蕴状态是存储在享元对象内部的,而且是不会随环境改变而有所不一样的。所以一个享元能够具备内蕴状态并能够共享。一个外蕴状态是随环境改变而改变的、不能够共享的状态。享元对象的外蕴状态必须由客户端保存,并在享元对象被建立以后,在须要使用的时候再传入到享元对象内部。外蕴状态不能够影响享元对象的内蕴对象。换句话说,它们是互相独立的。ide

其适用性:测试

一个应用程序使用了大量的对象,this

彻底因为使用大量的对象,形成很大的存储开销,spa

对象的大多数状态均可变为外部状态,设计

若是删除对象的外部状态,那么能够用相对较少的共享对象取代不少组对象,code

应用程序不依赖于对象标识。因为Flyweight对象能够被共享,对于概念上明显有别的对象,标识测试将返回真值。对象

  结构以下:blog

           

  享元模式在使用时分为单纯享元模式和复合享元模式两种,单纯享元模式中Flyweight都是可共享的,也是如今Flyweight实现的较多实例。如今先列出单纯享元模式:继承

 Flyweight.java

package org.designpattern.structural.flyweight;

    public  abstract  class Flyweight {
          protected  Character  intrinsicState;

          protected Flyweight( Character  intrinsicState){
              this.intrinsicState = intrinsicState;
         };
          public  abstract   void  operation(String extrinsicState);
          public  Character  getIntrinsicState(){
              return  this.intrinsicState;
         };
     }

  ConcreteFlyweight.java继承了Flyweight,实现了一个operation方法,类略。Flyweight是经过工厂获得的,下面是FlyweightFactory.java

package  org.designpattern.structural.flyweight;
import java.util.HashMap;

public  class FlyweightFactory {
     private HashMap flyWeights;
        public FlyweightFactory(){
         flyWeights =  new HashMap();
    }
     public Flyweight getFlyweight(Character key){
          if( this.flyWeights.containsKey(key)){
            System.out.println(key + " already created!");
             return (Flyweight) flyWeights.get(key);
        } else{
             Flyweight flyweight =  new ConcreteFlyweight(key);
             flyWeights.put(key,flyweight);
              return flyweight;
        }
    }

  若是是单纯享元模式,到这里再加上客户测试类就结束了。若是使用复合享元模式,复合元素的对象的状态是会改变的,因此复合享元对象是不能共享的。须要再增长一个类UnsharedConcreteFlyeweight.java

public class UnsharedConcreteFlyweight extends Flyweight {

     private HashMap<Character,Flyweight> unsharedFlyweights;
     private Flyweight  flyweight;

     public UnsharedConcreteFlyweight(Character intrinsicState) {
         super(intrinsicState);
         this.unsharedFlyweights =  new HashMap(20);
    }

     public  void add(Character key,Flyweight flyweight){
         this.unsharedFlyweights.put(key,flyweight);
    }
    @Override
     public  void operation(String extrinsicState) {
        System.out.println("extrinsicState:" + extrinsicState);
        Iterator<Map.Entry<Character,Flyweight>> it = unsharedFlyweights.entrySet().iterator();
         while(it.hasNext()){
            Map.Entry<Character,Flyweight> entry = it.next();
            Flyweight fly = entry.getValue();
            fly.operation(extrinsicState);
        }
    }

   } 

此时在FlyweighFactory.java中须要增长一个方法支持不可共享的Flyweight的调用:

 public Flyweight getUnsharedFlyweight(String keys ){

        UnsharedConcreteFlyweight unsharedConcreteFlyweight =  new UnsharedConcreteFlyweight( null);
         for( int i=0;i<keys.length();i++){
            Character character =  new Character(keys.charAt(i));
            unsharedConcreteFlyweight.add(character,getFlyweight(character));
        }
         return unsharedConcreteFlyweight;

    }

 下面是客户测试类:

   package  org.designpattern.structural.flyweight;
   public  class Main {
     public  static  void main(String[] args) {
        FlyweightFactory factory =  new FlyweightFactory();
        Flyweight fly1 = factory.getFlyweight('a');
        fly1.operation("First call!");
        Flyweight fly2 = factory.getFlyweight('b');
        fly2.operation("Second call!");
        Flyweight fly3 = factory.getFlyweight('a');
        fly3.operation("Third call!");
        System.out.println(fly1 == fly3);

        Flyweight unsharedFlyweight = factory.getUnsharedFlyweight("abcde");
        unsharedFlyweight.operation("Forth call!");
     }

  } 

 享元模式的有效性很大程度上取决于在何种情景下使用它,其主要缺点是使系统设计变得更加复杂,将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。咱们一般会把Flyweight工厂设计为单例模式,其能够和许多模式共同使用更有效。

相关文章
相关标签/搜索