黑马程序员技术交流社区

标题: 什么是享元设计模式? [打印本页]

作者: 于汝国    时间: 2011-12-23 00:06
标题: 什么是享元设计模式?
本帖最后由 于汝国 于 2011-12-23 09:26 编辑

享元设计模式到底是怎么一回事?这种设计模式具体在什么地方会用到?另外请用代码示例说明
作者: 郝锡强    时间: 2011-12-23 00:20
享元模式(英语:Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。享元模式利用只载立执行立即小任务所必需的资料,因而减少内存使用量。典型的享元模式的例子为文书处理器中以图形结构来表示字符。一个做法是,每个字形有其字型外观, 字模 metrics, 和其它格式资讯,但这会使每个字符就耗用上千字节。取而代之的是,每个字符参照到一个共享字形物件,此物件会被其它有共同特质的字符所分享;只有每个字符(文件中或页面中)的位置才需要另外储存。
自己描述比如:将4个箭头的方向分开存储,但箭头这个对象共享,这样只需要存储一个箭头元素,4个方向就可以了,目的为了节约内存。
Flyweight Pattern 轻量级,蝇量级

作者: 黑马巩伟伟    时间: 2011-12-23 00:30
其实说简单点就是把多次重复用到的对象第一次创建后就保存在内存中,之后只要用到该对象就直接拿,不用再创建新的对象。这样一来就节省了空间,提高的效率。
作者: 于汝国    时间: 2011-12-23 08:24
谢谢,有些明白了,共享同一个个对象元素,节省内存空间,提高效率......
作者: 王胜利    时间: 2011-12-23 08:56
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对象! ");
  }
}


作者: 杨强    时间: 2011-12-23 09:22
于汝国 发表于 2011-12-23 08:24
谢谢,有些明白了,共享同一个个对象元素,节省内存空间,提高效率......

如果问题解决了 点编辑 改成已解决




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2