大话设计模式
字体: 16 + -

第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