您好,登錄后才能下訂單哦!
本文實(shí)例講述了Java設(shè)計(jì)模式之享元模式。分享給大家供大家參考,具體如下:
解釋一下概念:也就是說(shuō)在一個(gè)系統(tǒng)中如果有多個(gè)相同的對(duì)象,那么只共享一份就可以了,不必每個(gè)都去實(shí)例化一個(gè)對(duì)象。比如說(shuō)一個(gè)文本系統(tǒng),每個(gè)字母定一個(gè)對(duì)象,那么大小寫(xiě)字母一共就是52個(gè),那么就要定義52個(gè)對(duì)象。如果有一個(gè)1M的文本,那么字母是何其的多,如果每個(gè)字母都定義一個(gè)對(duì)象那么內(nèi)存早就爆了。那么如果要是每個(gè)字母都共享一個(gè)對(duì)象,那么就大大節(jié)約了資源。
在Flyweight模式中,由于要產(chǎn)生各種各樣的對(duì)象,所以在Flyweight(享元)模式中常出現(xiàn)Factory模式。Flyweight的內(nèi)部狀態(tài)是用來(lái)共享的,Flyweight factory負(fù)責(zé)維護(hù)一個(gè)對(duì)象存儲(chǔ)池(Flyweight Pool)來(lái)存放內(nèi)部狀態(tài)的對(duì)象。Flyweight模式是一個(gè)提高程序效率和性能的模式,會(huì)大大加快程序的運(yùn)行速度.應(yīng)用場(chǎng)合很多,下面舉個(gè)例子:
先定義一個(gè)抽象的Flyweight類(lèi):
package Flyweight; public abstract class Flyweight{ public abstract void operation(); }
實(shí)現(xiàn)一個(gè)具體類(lèi):
package Flyweight; public class ConcreteFlyweight extends Flyweight{ private String string; public ConcreteFlyweight(String str){ string = str; } public void operation() { System.out.println("Concrete---Flyweight : " + string); } }
實(shí)現(xiàn)一個(gè)工廠(chǎng)方法類(lèi):
package Flyweight; import java.util.Hashtable; public class FlyweightFactory{ private Hashtable flyweights = new Hashtable();//----------------------------1 public FlyweightFactory(){} public Flyweight getFlyWeight(Object obj){ Flyweight flyweight = (Flyweight) flyweights.get(obj);//----------------2 if(flyweight == null){//---------------------------------------------------3 //產(chǎn)生新的ConcreteFlyweight flyweight = new ConcreteFlyweight((String)obj); flyweights.put(obj, flyweight);//--------------------------------------5 } return flyweight;//---------------------------------------------------------6 } public int getFlyweightSize(){ return flyweights.size(); } }
這個(gè)工廠(chǎng)方法類(lèi)非常關(guān)鍵,這里詳細(xì)解釋一下:
在1處定義了一個(gè)Hashtable用來(lái)存儲(chǔ)各個(gè)對(duì)象;在2處選出要實(shí)例化的對(duì)象,在6處將該對(duì)象返回,如果在Hashtable中沒(méi)有要選擇的對(duì)象,此時(shí)變量flyweight為null,產(chǎn)生一個(gè)新的flyweight存儲(chǔ)在Hashtable中,并將該對(duì)象返回。
最后看看Flyweight的調(diào)用:
package Flyweight; import java.util.Hashtable; public class FlyweightPattern{ FlyweightFactory factory = new FlyweightFactory(); Flyweight fly1; Flyweight fly2; Flyweight fly3; Flyweight fly4; Flyweight fly5; Flyweight fly6; /** *//** Creates a new instance of FlyweightPattern */ public FlyweightPattern(){ fly1 = factory.getFlyWeight("Google"); fly2 = factory.getFlyWeight("Qutr"); fly3 = factory.getFlyWeight("Google"); fly4 = factory.getFlyWeight("Google"); fly5 = factory.getFlyWeight("Google"); fly6 = factory.getFlyWeight("Google"); } public void showFlyweight(){ fly1.operation(); fly2.operation(); fly3.operation(); fly4.operation(); fly5.operation(); fly6.operation(); int objSize = factory.getFlyweightSize(); System.out.println("objSize = " + objSize); } public static void main(String[] args){ System.out.println("The FlyWeight Pattern!"); FlyweightPattern fp = new FlyweightPattern(); fp.showFlyweight(); } }
下面是運(yùn)行結(jié)果:
Concrete---Flyweight : Google
Concrete---Flyweight : Qutr
Concrete---Flyweight : Google
Concrete---Flyweight : Google
Concrete---Flyweight : Google
Concrete---Flyweight : Google
objSize = 2
我們定義了6個(gè)對(duì)象,其中有5個(gè)是相同的,按照Flyweight模式的定義“Google”應(yīng)該共享一個(gè)對(duì)象,在實(shí)際的對(duì)象數(shù)中我們可以看出實(shí)際的對(duì)象卻是只有2個(gè)。
總結(jié):
Flyweight(享元)模式是如此的重要,因?yàn)樗軒湍阍谝粋€(gè)復(fù)雜的系統(tǒng)中大量的節(jié)省內(nèi)存空間。在JAVA語(yǔ)言中,String類(lèi)型就是使用了享元模式。String對(duì)象是final類(lèi)型,對(duì)象一旦創(chuàng)建就不可改變。在JAVA中字符串常量都是存在常量池中的,JAVA會(huì)確保一個(gè)字符串常量在常量池中只有一個(gè)拷貝。String a="abc",其中"abc"就是一個(gè)字符串常量。
熟悉java的應(yīng)該知道下面這個(gè)例子:
String a = "hello"; String b = "hello"; if(a == b) System.out.println("OK"); else System.out.println("Error");
輸出結(jié)果是:OK??梢钥闯鰅f條件比較的是兩a和b的地址,也可以說(shuō)是內(nèi)存空間
核心總結(jié),可以共享的對(duì)象,也就是說(shuō)返回的同一類(lèi)型的對(duì)象其實(shí)是同一實(shí)例,當(dāng)客戶(hù)端要求生成一個(gè)對(duì)象時(shí),工廠(chǎng)會(huì)檢測(cè)是否存在此對(duì)象的實(shí)例,如果存在那么直接返回此對(duì)象實(shí)例,如果不存在就創(chuàng)建一個(gè)并保存起來(lái),這點(diǎn)有些單例模式的意思。通常工廠(chǎng)類(lèi)會(huì)有一個(gè)集合類(lèi)型的成員變量來(lái)用以保存對(duì)象,如hashtable,vector等。在java中,數(shù)據(jù)庫(kù)連接池,線(xiàn)程池等即是用享元模式的應(yīng)用。
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。