第95章
大b:“我们前面已经提到,当大量从数据源中读取字符串,其中肯定有重复的,那么我们使用flyweight模式可以提高效率,以唱片cd为例,在一个xml文件中,存放了多个cd的资料。”
每个cd有三个字段:
1、出片日期(year)
2、歌唱者姓名等信息(artist)
3、唱片曲目(title)
其中,歌唱者姓名有可能重复,也就是说,可能有同一个演唱者的多个不同时期不同曲目的cd。我们将‘歌唱者姓名’作为可共享的concreteflyweight。其他两个字段作为unsharedconcreteflyweight。
首先看看数据源xml文件的内容:
《xmlversion=“1.0”?》
《collection》
《cd》
《title》anothergreenworld《/title》
《year》1978《/year》
《artist》eno,brian《/artist》
《/cd》
《cd》
《title》greatesthits《/title》
《year》1950《/year》
《artist》holiday,billie《/artist》
《/cd》
《cd》
《title》takingtigermountain(bystrategy)《/title》
《year》1977《/year》
《artist》eno,brian《/artist》
《/cd》
……
《/collection》
虽然上面举例cd只有3张,cd可看成是大量重复的小类,因为其中成份只有三个字段,而且有重复的(歌唱者姓名)。
cd就是类似上面接口flyweight:
publicclasscd{
privatestringtitle;
privateintyear;
privateartistartist;
publicstringgettitle(){returntitle;}
publicintgetyear(){returnyear;}
publicartistgetartist(){returnartist;}
publicvoidsettitle(stringt){title=t;}
publicvoidsetyear(inty){year=y;}
publicvoidsetartist(artista){artist=a;}
}
将“歌唱者姓名”作为可共享的concreteflyweight:
publicclassartist{
//内部状态
privatestringname;
//notethatartistisimmutable.
stringgetname(){returnname;}
artist(stringn){
name=n;
}
}
再看看flyweightfactory,专门用来制造上面的可共享的concreteflyweight:artist
publicclassartistfactory{
hashtablepool=newhashtable();
artistgetartist(stringkey){
artistresult;
result=(artist)pool.get(key);
////产生新的。
if(result……null){
result=newartist(key);
pool.put(key,result);
}
returnresult;
}
}
当你有几千张甚至更多cd时,flyweight模式将节省更多空间,共享的flyweight越多,空间节省也就越大。
给个例子,coffee商店
packageflyweight.coffeeshop;
publicclasstable{
privateintnumber;
publicintgetnumber(){
returnnumber;
}
publicvoidsetnumber(intnumber){
this.number=number;
}
publictable(intnumber){
super();
//todoauto-generatedconstructorstub
this.number=number;
}
}
packageflyweight.coffeeshop;
publicabstractclassorder{?
publicabstractvoidserve(tabletable);
publicabstractstringgetflavor();
}
packageflyweight.coffeeshop;
publicclassflavorextendsorder{
privatestringflavor;
publicflavor(stringflavor){
super();
//todoauto-generatedconstructorstub
this.flavor=flavor;
}
publicstringgetflavor(){
returnflavor;
}
publicvoidsetflavor(stringflavor){
this.flavor=flavor;
}
publicvoidserve(tabletable){
system.out.println(“servingtable”+table.getnumber()+“withflavor”+flavor);
}
}
packageflyweight.coffeeshop;
publicclassflavorfactory{
privateorder[]flavors=newflavor[10];
privateintordersmade=0;//已经处理好的订单数
privateinttotalflavors=0;//已购买的coffee风味种类数
publicordergetorder(stringflavortoget){
if(ordersmade>0){
for(inti=0;i