大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; Wωω▪ ttkan▪ C○
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