大B:“我们前面已经提到,当大量从数据源中读取字符串,其中肯定有重复的,那么我们使用Flyweight模式可以提高效率,以唱片CD为例,在一个XML文件中,存放了多个CD的资料。”
每个CD有三个字段:
1、出片日期(year)
2、歌唱者姓名等信息(artist)
3、唱片曲目(title)
其中,歌唱者姓名有可能重复,也就是说,可能有同一个演唱者的多个不同时期不同曲目的CD。我们将‘歌唱者姓名’作为可共享的ConcreteFlyweight。其他两个字段作为UnsharedConcreteFlyweight。
首先看看数据源XML文件的内容:
《xmlversion=“www.youxs.org”?》
《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)(key);
////产生新的。
if(result……null){
result=newArtist(key);
(key,result);
returnresult;
当你有几千张甚至更多CD时,Flyweight模式将节省更多空间,共享的flyweight越多,空间节省也就越大。
给个例子,coffee商店
publicclassTable{
privateintnumber;
publicintgetNumber{
returnnumber;
publicvoidsetNumber(intnumber){
=number;
publicTable(intnumber){
super;
//TODOAuto-generatedconstructorstub
=number;
publicabstractclassOrder{?
publicabstractvoidserve(Tabletable);
publicabstractStringgetFlavor;
publicclassFlavorextendsOrder{
privateStringflavor;
publicFlavor(Stringflavor){
super;
//TODOAuto-generatedconstructorstub
=flavor;
publicStringgetFlavor{
returnflavor;
publicvoidsetFlavor(Stringflavor){
=flavor;
publicvoidserve(Tabletable){
(“Servingtable”++“withflavor”+flavor);
publicclassFlavorFactory{
privateOrderflavors=newFlavor[10];
privateintordersMade=0;//已经处理好的订单数
privateinttotalFlavors=0;//已购买的coffee风味种类数
publicOrdergetOrder(StringflavorToGet){
if(ordersMade>0){
for(inti=0;i