zoukankan      html  css  js  c++  java
  • 享元模式

        享元模式(Flyweight Pattern),Flyweight在拳击比赛中是最轻量级别--“蝇量级"。享元模式以共享的方式支持大量的细粒度对象。

        享元模式在编辑系统中被大量使用,例如字母a会在许多的地方出现,尽管所出现的位置和字模风格不尽相同,但是都可以共享一个字母a的对象。

         Java中的String是final的,改变String的内容就是一个新的String了。只要是内容相同,多个String对象是可以共享一个String实例的。

         享元模式可以分为单纯享元模式和复合享元模式两种。

         单纯享元模式中,所有享元对象都是可以共享的。下面是单纯享元模式的类图:

         

          核心是FlyweightFactory,采取的是登记的工厂方式,用HashMap存储已经构造的ConcreteFlyweight。调用时先去查看HashMap是否已经存在,已存在则直接调用。不存在时先创建再添加到HashMap中以共享使用。

          Flyweight接口的示例代码:    

    public abstract  class Flyweight{
        public abstract  void operation(String state);
    }

          具体类ConcreteFlyweight的示例代码:

    public class ConcreteFlyweight extends Flyweight{
        private Character intrinsicState = null;
    
        public ConcreteFlyweight(Character state){ 
           this.intrinsicState = state;
        }
        
        public void operation(String state){ 
         System.out.print( "
    Intrinsic State = " + intrinsicState +
                ", Extrinsic State = " + state);
        }
    }

            工厂类FlyweightFactory的示例代码:

    public class FlyweightFactory{
        private HashMap flies = new HashMap();
        private Flyweight lnkFlyweight;
        public FlyweightFactory(){
        }
        
        public synchronized Flyweight factory(Character state){ 
        if (flies.containsKey(state)){
                return (Flyweight)flies.get(state);
        }
        else{
                Flyweight fly = new ConcreteFlyweight(state);
                flies.put(state, fly);
                return fly;
            }
        }
        
        public void checkFlyweight(){ 
        Flyweight fly ;
            int i = 0;
    
            System.out.println("
    ==========checkFlyweight()=============");
        for (Iterator it = flies.entrySet().iterator() ; it.hasNext(); ){
            Map.Entry e = (Map.Entry) it.next();
                System.out.println("Item " + (++i) + " : " + e.getKey());
            }
            System.out.println("==========checkFlyweight()=============");
       }
    }

          客户端client的示例代码:

    public class Client{
        private static FlyweightFactory factory;
    
        public static  void main(String[] args){ 
        factory = new FlyweightFactory();
    
        Flyweight fly = factory.factory(new Character('a'));
        fly.operation("First Call");
            
        fly = factory.factory(new Character('b'));
        fly.operation("Second Call");
            
        fly = factory.factory(new Character('a'));
        fly.operation("Third Call");
            
        // intrinsic Flyweight
        factory.checkFlyweight();
       } 
    }

           客户端client在创建2个对象”a”时实际上是共享了一个对象。

           复合享元模式的类图如下所示:

           

          共享的不再是单纯的对象,而是由合成模式合成的复杂对象。类图中的Flyweight,ConcreteFlyweight和ConcreteCompositeFlyweight就构成了合成模式。ConcreteCompositeFlyweight中可以包含ConcreteFlyweight,从而合成更为复杂的对象。

          和单纯享元模式相比较,变化较大是FlyweightFactory和ConcreteCompositeFlyweight。

          下面是FlyweightFactory的实例代码。 加入了一个factory(String compositeState) ,compositeState的每个字符被作为一个ConcreteFlyweight加入到ConcreteCompositeFlyweight中。实际应用中compositeState应该是Vector<Object>。

    public class FlyweightFactory{
    
        private HashMap flies = new HashMap();
        private Flyweight lnkFlyweight;
    
        public FlyweightFactory(){}
    
        public Flyweight factory(String compositeState){ 
           ConcreteCompositeFlyweight compositeFly = new ConcreteCompositeFlyweight();        
           int length = compositeState.length();
           Character state = null;
    
           for(int i = 0; i < length; i++){ 
             state = new Character(compositeState.charAt(i) );
             System.out.println("factory(" + state + ")");
             compositeFly.add(state, this.factory( state) );
           }
           return compositeFly;
        }
    
        public Flyweight factory(Character state){ 
        if ( flies.containsKey(state)){
                return (Flyweight) flies.get( state );
            }
            else{
            Flyweight fly = new ConcreteFlyweight( state );
                flies.put( state , fly);
                return fly;
            }
        }
        
        public void checkFlyweight(){ 
            Flyweight fly ;
            int i = 0 ;
    
            System.out.println("
    ==========checkFlyweight()=============");
            for ( Iterator it = flies.entrySet().iterator() ; it.hasNext(); ){
                Map.Entry e = (Map.Entry) it.next();
                System.out.println( "Item " + (++i) + " : " + e.getKey());
            }
            System.out.println("
    ==========checkFlyweight()=============");
         }
    }

          ConcreteCompositeFlyweight的示例代码为:

    public class ConcreteCompositeFlyweight extends Flyweight {
        private HashMap flies = new HashMap(10);
    
        private Flyweight flyweight;
    
        public ConcreteCompositeFlyweight(){ 
        }
        
        public void add(Character key, Flyweight fly){ 
        flies.put(key, fly);
        }
        
        public void operation(String extrinsicState){
            Flyweight fly =  null;
    
        for (Iterator it = flies.entrySet().iterator();it.hasNext();){
            Map.Entry e = (Map.Entry) it.next();
                fly = (Flyweight) e.getValue();
                fly.operation(extrinsicState);
            }
        }
    }

            一个咖啡摊的例子,咖啡摊虽然每天卖出的咖啡数量很多,但是咖啡的种类是固定且有限的,这里享元模式就很适用。类图如下:

            

          单纯享元模式就很合适,Order充当了抽象接口,Flavor是具体的实现,FlavorFactory采用的是登记的工厂模式。

          订单的代码:

    public abstract class Order{  
        public abstract void serve();
        public abstract String getFlavor();
    }

          咖啡的代码:

    public class Flavor extends Order{  
        private String flavor;    
        public Flavor(String flavor){
            this.flavor = flavor;
        }
        
        public String getFlavor(){
            return this.flavor;
        }
        
        public void serve(){
            System.out.println("Serving flavor " + flavor );
        }
    }

          工厂类的代码;

    public class FlavorFactory{  
        private Order[] flavors = new Flavor[10];
        private int ordersMade = 0;
        private int totalFlavors = 0 ;
        
        public Order getOrder(String flavorToGet){
          if (ordersMade > 0){
             for (int i = 0; i < ordersMade; i++){
                  if (flavorToGet.equals((flavors[i]).getFlavor())){
                        return flavors[i];
                  }
              }
          }
          flavors[ordersMade] = new Flavor(flavorToGet);
          totalFlavors++;
          return flavors[ordersMade++];
       }
        
       public int getTotalFlavorsMade(){
         return totalFlavors;
       }
    }

          客户端的代码:

    public class Client{
        
         private static Order[] flavors = new Flavor[100];
         private static int ordersMade = 0;
         private static FlavorFactory flavorFactory;
         
         private static void takeOrders(String aFlavor){
             flavors[ordersMade++] = flavorFactory.getOrder(aFlavor);
         }
         
         public static void main(String[] args) {
            flavorFactory = new FlavorFactory();
            
            takeOrders("Black Coffee");
            takeOrders("Capucino");
            takeOrders("Espresso");
            takeOrders("Espresso");
            takeOrders("Capucino");
            takeOrders("Capucino");
            takeOrders("Black Coffee");
            takeOrders("Espresso");
            takeOrders("Capucino");
            takeOrders("Black Coffee");
            takeOrders("Espresso");
    
         for (int i = 0; i < ordersMade; i++){
             flavors[i].serve();
         }
    
         System.out.println("
    Total teaFlavor objects made: " +
                flavorFactory.getTotalFlavorsMade());
        }
    }

        从flavorFactory.getTotalFlavorsMade()的结果可以看出,工厂类中登记的咖啡种类只哟3种。

           

  • 相关阅读:
    2、容器初探
    3、二叉树:先序,中序,后序循环遍历详解
    Hebbian Learning Rule
    论文笔记 Weakly-Supervised Spatial Context Networks
    在Caffe添加Python layer详细步骤
    论文笔记 Learning to Compare Image Patches via Convolutional Neural Networks
    Deconvolution 反卷积理解
    论文笔记 Feature Pyramid Networks for Object Detection
    Caffe2 初识
    论文笔记 Densely Connected Convolutional Networks
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/3952483.html
Copyright © 2011-2022 走看看