大B:“我们前面已经提到,当大量从数据源中读取字符串,其中肯定有重复的,那么我们使用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);
////产生新的。
if(result……null){
result=new Artist(key);
pool。put(key,result);
}
return result;
}
}
当你有几千张甚至更多CD时,Flyweight模式将节省更多空间,共享的flyweight越多,空间节省也就越大。
给个例子,coffee商店
package FlyWeight。coffeeshop;
public class Table{
private int number;
public int getNumber(){
return number;
}
public void setNumber(int number){
this。number=number;
}
public Table(int number){
super();
//TODO Auto-generated constructor stub
this。number=number;
}
}
package FlyWeight。coffeeshop;
public abstract class Order{?
public abstract void serve(Table table);
public abstract String getFlavor();
}
package FlyWeight。coffeeshop;
public class Flavor extends Order{
private String flavor;
public Flavor(String flavor){
super();
//TODO Auto-generated constructor stub
this。flavor=flavor;
}
public String getFlavor(){
return flavor;
}
public void setFlavor(String flavor){
this。flavor=flavor;
}
public void serve(Table table){
System。out。println(“Serving table” table。getNumber() “with flavor” flavor);
}
}
package FlyWeight。coffeeshop;
public class FlavorFactory{
private Order[]flavors=new Flavor[10];
private int ordersMade=0;//已经处理好的订单数
private int totalFlavors=0;//已购买的coffee风味种类数
public Order getOrder(String flavorToGet){
if(ordersMade>;0){
for(int i=0;i<ordersmade;i ){
if(flavorToGet。equalsIgnoreCase(flavors[i]。getFlavor()))
return flavors[i];
}
}
flavors[ordersMade]=new Flavor(flavorToGet);
totalFlavors ;
return flavors[ordersMade ];
}
public int getTotalFlavorsMade(){
return totalFlavors;
}
}
package FlyWeight。coffeeshop;
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(new Table(i));
}
System。out。println(\nTotal Flavor objrcts made:
flavorFactory。getTotalFlavorsMade());
}
}
//――
运行结果:
Serving table 0 with flavor Black Coffee
Serving table 1 with flavor Capucino
Serving table 2 with flavor Espresso
Serving table 3 with flavor Espresso
Serving table 4 with flavor Capucino
Serving table 5 with flavor Capucino
Serving table 6 with flavor Black Coffee
Serving table 7 with flavor Espresso
Serving table 8 with flavor Capucino
Serving table 9 with flavor Black Coffee
Serving table 10 with flavor Espresso
</ordersmade;i ){
</ordersmade;i ){