/用于本模式的抽象数据类型(自行设计) public interface ExtrinsicState { 下面是接口的具体实现(ConcreteFlyweight),并为内部状态增加内存空间, ConcreteFlyweight必须是可共享的,它保存的任何状态都必须是内部(intrinsic), 也就是说,ConcreteFlyweight必须和它的应用环境场合无关. public class ConcreteFlyweight implements Flyweight private Intrinsicstate state; public void operation(ExtrinsicState state /具体操作 } 当然,并不是所有的lyweight具体实现子类都需要被共享的,所以还有另外一种不 共享的ConcreteFlyweight: public class UnsharedConcreteFlyweight implements Flyweight public void operation(ExtrinsicState state ){ Flyweight factory负责维护一个Flyweight池(存放内部状态),当客户端请求 一个共享Flyweight时,这个factory首先搜索池中是否已经有可适用的,如果
} //用于本模式的抽象数据类型(自行设计) 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 flyl factory.getFlyweight("Fred") Flyweight fly2 factory.getFlyweight "Wilma")
有,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.唱片曲目(tit1e) 其中,歌唱者姓名有可能重复,也就是说,可能有同一个演唱者的多个不同时期不同 曲目的cD.我们将"歌唱者姓名"作为可共享的ConcreteFlyweight.其他两个字段作为 UnsharedConcreteFlyweight. 首先看看数据源ML文件的内容: <?xml version="1.0"?> <collection> <cd> <title>Another Green World</title> <year>1978</year> <artist>Eno,Brian</artist>
...... 从调用上看,好象是个纯粹的 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;
</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; }
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; } }