选择显示字体大小

java模式研究袖珍版之flyweight模式


  flyweight定义:

  避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类).

  为什么使用?

  面向对象语言的原则就是一切都是对象,但是如果真正使用起来,有时对象数可能显得很庞大,比如,字处理软件,如果以每个文字都作为一个对象,几千个字,对象数就是几千,无疑耗费内存,那么我们还是要"求同存异",找出这些对象群的共同点,设计一个元类,封装可以被共享的类,另外,还有一些特性是取决于应用(context),是不可共享的,这也flyweight中两个重要概念内部状态intrinsic和外部状态extrinsic之分.


  说白点,就是先捏一个的原始模型,然后随着不同场合和环境,再产生各具特征的具体模型,很显然,在这里需要产生不同的新对象,所以flyweight模式中常出现factory模式.flyweight的内部状态是用来共享的,flyweight factory负责维护一个flyweight pool(模式池)来存放内部状态的对象.

  flyweight模式是一个提高程序效率和性能的模式,会大大加快程序的运行速度.应用场合很多:比如你要从一个数据库中读取一系列字符串,这些字符串中有许多是重复的,那么我们可以将这些字符串储存在flyweight池(pool)中.

  如何使用?

  我们先从flyweight抽象接口开始:

  程序代码:
 

public interface flyweight
{
  public void operation( extrinsicstate state );
}
//用于本模式的抽象数据类型(自行设计)
public interface extrinsicstate { }

  下面是接口的具体实现(concreteflyweight) ,并为内部状态增加内存空间, concreteflyweight必须是可共享的,它保存的任何状态都必须是内部(intrinsic),也就是说,concreteflyweight必须和它的应用环境场合无关.

  程序代码:

 
public class concreteflyweight implements flyweight {
  private intrinsicstate state;
  
  public void operation( extrinsicstate state )
  {
      //具体操作
  }
}   当然,并不是所有的flyweight具体实现子类都需要被共享的,所以还有另外一种不共享的concreteflyweight:

  程序代码:

 
public class unsharedconcreteflyweight implements flyweight {
  public void operation( extrinsicstate state ) { }
}
 flyweight factory负责维护一个flyweight池(存放内部状态),当客户端请求一个共享flyweight时,这个factory首先搜索池中是否已经有可适用的,如果有,factory只是简单返回送出这个对象,否则,创建一个新的对象,加入到池中,再返回送出这个对象.池

  程序代码:


 
public class flyweightfactory {
  //flyweight pool
  private hashtable flyweights = new hashtable();
  public flyweight getflyweight( object key ) {
    flyweight flyweight = (flyweight) flyweights.get(key);
    if( flyweight == null ) {
      //产生新的concreteflyweight
      flyweight = new concreteflyweight();
      flyweights.put( key, flyweight );
    }
    return flyweight;
  }
}

  至此,flyweight模式的基本框架已经就绪,我们看看如何调用:

  程序代码:

 
flyweightfactory factory = new flyweightfactory();
flyweight fly1 = factory.getflyweight( "fred" );
flyweight fly2 = factory.getflyweight( "wilma" );
......

  从调用上看,好象是个纯粹的factory使用,但奥妙就在于factory的内部设计上.

  flyweight模式xml等数据源中应用

  我们上面已经提到,当大量从数据源中读取字符串,其中肯定有重复的,那么我们使用flyweight模式可以提高效率,以唱片cd为例,在一个xml文件中,存放了多个cd的资料.

  每个cd有三个字段:

  1.出片日期(year)

  2.歌唱者姓名等信息(artist)

  3.唱片曲目 (title)

  其中,歌唱者姓名有可能重复,也就是说,可能有同一个演唱者的多个不同时期 不同曲目的cd.我们将"歌唱者姓名"作为可共享的concreteflyweight.其他两个字段作为unsharedconcreteflyweight.

  首先看看数据源xml文件的内容:

  程序代码:
<?xml version="1.0"?>

<collection>

 <cd>
  <title>another green world</title>
  <year>1978</year>
  <artist>eno, brian</artist>
 </cd>

 <cd>
  <title>greatest hits</title>
  <year>1950</year>
  <artist>holiday, billie</artist>
 </cd>

 <cd>
  <title>taking tiger mountain (by strategy)</title>
  <year>1977</year>
  <artist>eno, brian</artist>
 </cd>
 .......
</collection>


  虽然上面举例cd只有3张,cd可看成是大量重复的小类,因为其中成分只有三个字段,而且有重复的(歌唱者姓名).

  cd就是类似上面接口 flyweight:

  程序代码:

 
public class cd {

  private string title;
  private int year;
  private artist artist;

  public string gettitle() {  return title; }
  public int getyear() {    return year;  }
  public artist getartist() {    return artist;  }

  public void settitle(string t){    title = t;}
  public void setyear(int y){year = y;}
  public void setartist(artist a){artist = a;}

}

  将"歌唱者姓名"作为可共享的concreteflyweight:

  程序代码:

 
public class artist {
  //内部状态
  private string name;
  // note that artist is immutable.
  string getname(){return name;}
  artist(string n){
    name = n;
  }
}

  再看看flyweight factory,专门用来制造上面的可共享的concreteflyweight:artist

  程序代码:

 
public class artistfactory {
  hashtable pool = new hashtable();
  artist getartist(string key){
    artist result;
    result = (artist)pool.get(key);
    ////产生新的artist
    if(result == null) {
      result = new artist(key);
      pool.put(key,result);
      
    }
    return result;
  }
}

  当你有几千张甚至更多cd时,flyweight模式将节省更多空间,共享的flyweight越多,空间节省也就越大.


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons