例子應(yīng)用:
比如說(shuō)一個(gè)文本系統(tǒng),每個(gè)字母定一個(gè)對(duì)象,那么大小寫字母一共就是52個(gè),那么就要定義52個(gè)對(duì)象。如果有一個(gè)1M的文本,那么字母是何其的多,如果每個(gè)字母都定義一個(gè)對(duì)象那么內(nèi)存早就爆了。那么如果要是每個(gè)字母都共享一個(gè)對(duì)象,那么就大大節(jié)約了資源。
在Java語(yǔ)言中,String類型就是使用了享元模式。String對(duì)象是final類型,對(duì)象一旦創(chuàng)建就不可改變。在JAVA中字符串常量都是存在常量池中的,JAVA會(huì)確保一個(gè)字符串常量在常量池中只有一個(gè)拷貝。String a="abc",其中"abc"就是一個(gè)字符串常量。
數(shù)據(jù)庫(kù)連接池,線程池等即是用享元模式的應(yīng)用。
什么是享元模式
大量細(xì)粒度對(duì)象共享復(fù)用。復(fù)用我們內(nèi)存中已存在的對(duì)象,降低系統(tǒng)創(chuàng)建對(duì)象實(shí)例的性能消耗。
享元模式:“享”就是分享之意,指一物被眾人共享,而這也正是該模式的終旨所在。
享元模式有點(diǎn)類似于單例模式,都是只生成一個(gè)對(duì)象來(lái)被共享使用。這里有個(gè)問(wèn)題,那就是對(duì)共享對(duì)象的修改,為了避免出現(xiàn)這種情況,我們將這些對(duì)象的公共部分,或者說(shuō)是不變化的部分抽取出來(lái)形成一個(gè)對(duì)象。這個(gè)對(duì)象就可以避免到修改的問(wèn)題。
主要解決
在有大量對(duì)象時(shí),有可能會(huì)造成內(nèi)存溢出,我們把其中共同的部分抽象出來(lái),如果有相同的業(yè)務(wù)請(qǐng)求,直接返回在內(nèi)存中已有的對(duì)象,避免重新創(chuàng)建。
何時(shí)使用
1、系統(tǒng)中有大量對(duì)象。
2、這些對(duì)象消耗大量?jī)?nèi)存。
3、需要緩沖池的場(chǎng)景。
4、這些對(duì)象的狀態(tài)大部分可以外部化。
5、這些對(duì)象可以按照內(nèi)蘊(yùn)狀態(tài)分為很多組,當(dāng)把外蘊(yùn)對(duì)象從對(duì)象中剔除出來(lái)時(shí),每一組對(duì)象都可以用一個(gè)對(duì)象來(lái)代替。
6、系統(tǒng)不依賴于這些對(duì)象身份,這些對(duì)象是不可分辨的。
7、當(dāng)我們系統(tǒng)中某個(gè)對(duì)象類型的實(shí)例較多的情況,并且要求這些實(shí)例進(jìn)行分類后,發(fā)現(xiàn)真正有區(qū)別的分類很少的情況。
如何解決
用唯一標(biāo)識(shí)碼判斷,如果在內(nèi)存中有,則返回這個(gè)唯一標(biāo)識(shí)碼所標(biāo)識(shí)的對(duì)象。
關(guān)鍵代碼
用 HashMap 存儲(chǔ)這些對(duì)象。
優(yōu)點(diǎn)
大大減少對(duì)象的創(chuàng)建,節(jié)約內(nèi)存空間,降低系統(tǒng)的內(nèi)存,提高系統(tǒng)的性能。
缺點(diǎn)
提高了系統(tǒng)的復(fù)雜度,需要分離出外部狀態(tài)和內(nèi)部狀態(tài),而且外部狀態(tài)具有固有化的性質(zhì),不應(yīng)該隨著內(nèi)部狀態(tài)的變化而變化,否則會(huì)造成系統(tǒng)的混亂。
享元模式一般是給出本地內(nèi)存資源節(jié)省的一個(gè)方案,并不適合互聯(lián)網(wǎng)上的分布式應(yīng)用的情況,不過(guò)享元模式對(duì)于排他性的要求資源的控制,是個(gè)不錯(cuò)的選擇的。
注意事項(xiàng):
1、注意劃分外部狀態(tài)和內(nèi)部狀態(tài),否則可能會(huì)引起線程安全問(wèn)題。
2、這些類必須有一個(gè)工廠對(duì)象加以控制。
內(nèi)部狀態(tài)、外部狀態(tài)。
內(nèi)部狀態(tài):在享元對(duì)象內(nèi)部不隨外界環(huán)境改變而改變的共享部分。
外部狀態(tài):隨著環(huán)境的改變而改變,不能夠共享的狀態(tài)就是外部狀態(tài)。
內(nèi)部狀態(tài)存儲(chǔ)于享元對(duì)象內(nèi)部,而外部狀態(tài)則應(yīng)該由客戶端來(lái)考慮。
享元工廠類
享元模式的核心在于享元工廠類,享元工廠類的作用在于提供一個(gè)用于存儲(chǔ)享元對(duì)象的享元池,用戶需要對(duì)象時(shí),首先從享元池中獲取,如果享元池中不存在,則創(chuàng)建一個(gè)新的享元對(duì)象返回給用戶,并在享元池中保存該新增對(duì)象。
角色
抽象享元:一個(gè)接口或抽象類;
具體享元:內(nèi)部狀態(tài)為其成員屬性,其實(shí)例為享元對(duì)象,可以共享;
享元工廠:生產(chǎn)享元對(duì)象,將具體享元對(duì)象存儲(chǔ)在一個(gè)享元池中,享元池一般設(shè)計(jì)為一個(gè)存儲(chǔ)“鍵值對(duì)”的集合;
客戶端:使用享元對(duì)象
http://www.cnblogs.com/V1haoge/p/6542449.html
http://blog.csdn.net/jason0539/article/details/22908915
http://www.runoob.com/design-pattern/flyweight-pattern.html
http://www.cnblogs.com/hegezhou_hot/archive/2010/12/12/1903728.html