zoukankan      html  css  js  c++  java
  • 设计模式之flyweight享元模式

     运用共享技术支持大量细粒度对象的使用

                                             Flyweight模式(享元)
       Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的 中型系统中应用广泛,遵循一定的编程模式,才能使自己的代码便于理解,易于交流,Flyweight(享元模式)模式是比较常用的一个模式。
       Flyweight模式是一个提高程序效率和性能的模式,会大大加快程序的运行速度.应用场合很多:比如你要从一个数据库中读取一系列字符串,这些字符串中有许多是重复的,那么我们可以将这些字符串储存在Flyweight池(pool)中.
       定义:避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类)。
       设计初衷:面向对象语言的原则就是一切都是对象,但是如果真正使用起来,有时对象数可能显得很庞大,比如,字处理软件,如果以每个文字都作为一个对象,几 千个字,对象数就是几千,无疑耗费内存,那么我们还是要"求同存异",找出这些对象群的共同点,设计一个元类,封装可以被共享的类,另外,还有一些特性是 取决于应用(context),是不可共享的.
      
       在此 以咖啡外卖店为例 写了4个java类来描述说明Flyweight设计模式的实现方式;
       客户买咖啡下订单,订单只区分咖啡口味,如果下了1W个订单,而咖啡店只卖20种口味的咖啡,那么我们就没有必要生成1W个订单对象,通过享元模式我们只需要生成20个订单对象。
       这个例子举的不太好,但足以说明问题。下面是具体的代码。
      

      1、 Order.java         订单抽象类
      2、 FlavorOrder.java   订单实现类
      3、 FlavorFactory.java 订单生成工厂
      4、 Client.java        客户类、带有main方法的测试类

    ===============   1、 Order.java
    package flyweight;

    public abstract class Order {
      //执行卖出动作
      public abstract void sell();
      //获取咖啡口味
      public abstract String getFlavor();
    }
    ===============   1   end

    ===============   2、 FlavorOrder.java
    package flyweight;

    public class FlavorOrder extends Order{ 
      private String flavor;
     
      public FlavorOrder(String flavor){
          this.flavor = flavor;
      }
     
      public String getFlavor(){
          return this.flavor;
      }

      public void sell(){
          System.out.println("卖出一杯 [" + flavor + "]。" );
      }
    }
    ===============   2   end

    ===============   3、 FlavorFactory.java
    package flyweight;

    import java.util.HashMap;
    import java.util.Map;

    public class FlavorFactory {
      //订单池
      private Map<String,Order> flavorPool = new HashMap<String,Order>(20);

      //静态工厂,负责生成订单对象
      private static FlavorFactory flavorFactory = new FlavorFactory();

      private FlavorFactory() {}

      public static FlavorFactory getInstance() {
        return flavorFactory;
      }

      //获得订单
      public Order getOrder(String flavor) {
        Order order = null;
        if(flavorPool.containsKey(flavor)){
          order = flavorPool.get(flavor);
        }else{
          //获得新口味订单
          order = new FlavorOrder(flavor);
          //放入对象池
          flavorPool.put(flavor, order);   
        }
        return order;
      }

      //获得已经卖出的咖啡全部口味数量
      public int getTotalFlavorsMade() {
        return flavorPool.size();
      }
    }
    ===============   3   end

    ===============   4、 Client.java
    package flyweight;

    import java.util.ArrayList;
    import java.util.List;

    public class Client {
      //客户下的订单
      private static List<Order> orders = new ArrayList<Order>(100);

      //订单对象生成工厂
      private static FlavorFactory flavorFactory;

      //增加订单
      private static void takeOrders(String flavor) {
        orders.add(flavorFactory.getOrder(flavor));
      }

      public static void main(String[] args) {
        //订单生成工厂
        flavorFactory = FlavorFactory.getInstance();

        //增加订单
        takeOrders("摩卡");
        takeOrders("卡布奇诺");
        takeOrders("香草星冰乐");
        takeOrders("香草星冰乐");
        takeOrders("拿铁");
        takeOrders("卡布奇诺");
        takeOrders("拿铁");
        takeOrders("卡布奇诺");
        takeOrders("摩卡");
        takeOrders("香草星冰乐");
        takeOrders("卡布奇诺");
        takeOrders("摩卡");
        takeOrders("香草星冰乐");
        takeOrders("拿铁");
        takeOrders("拿铁");

        //卖咖啡
        for(Order order : orders){
          order.sell();
        }

        //打印生成的订单java对象数量
        System.out.println("n客户一共买了 " +  orders.size() + " 杯咖啡! ");

        //打印生成的订单java对象数量
        System.out.println("n共生成了 " +  flavorFactory.getTotalFlavorsMade() + " 个 FlavorOrder java对象! ");
      }
    }
    ===============   4   end

  • 相关阅读:
    .Net2.0 中 Page 页面的事件触发顺序
    vs 中自带的代码混淆器 Dotfuscator (图)
    SqlHelper 中文注释版(值得收藏)
    (原创)用重载实现 treeview 的无限分类递归调用(图)
    通过前置代码指定嵌套中的 Repeater 事件!
    vs2008 中提高开发效率的一些快捷键
    强内聚,弱耦合
    也谈 SQL 注入攻击。
    ASP.NET 页面中动态加载用户控件
    ASP 调用存储过程,同时返回记录集和输出参数
  • 原文地址:https://www.cnblogs.com/kexb/p/3671339.html
Copyright © 2011-2022 走看看