設(shè)計模式(十):享元模式

01.模式動機(jī)

面向?qū)ο蠹夹g(shù)可以很好地解決一些靈活性或可擴(kuò)展性問題,但在很多情況下需要在系統(tǒng)中增加類和對象的個數(shù)。當(dāng)對象數(shù)量太多時,將導(dǎo)致運(yùn)行代價過高,帶來性能下降等問題。

  • 享元模式正是為解決這一類問題而誕生的。享元模式通過共享技術(shù)實現(xiàn)相同或相似對象的重用。

  • 在享元模式中可以共享的相同內(nèi)容稱為內(nèi)部狀態(tài)(IntrinsicState),而那些需要外部環(huán)境來設(shè)置的不能共享的內(nèi)容稱為外部狀態(tài)(Extrinsic State),由于區(qū)分了內(nèi)部狀態(tài)和外部狀態(tài),因此可以通過設(shè)置不同的外部狀態(tài)使得相同的對象可以具有一些不同的特征,而相同的內(nèi)部狀態(tài)是可以共享的。

  • 在享元模式中通常會出現(xiàn)工廠模式,需要創(chuàng)建一個享元工廠來負(fù)責(zé)維護(hù)一個享元池(Flyweight Pool)用于存儲具有相同內(nèi)部狀態(tài)的享元對象。

  • 在享元模式中共享的是享元對象的內(nèi)部狀態(tài),外部狀態(tài)需要通過環(huán)境來設(shè)置。在實際使用中,能夠共享的內(nèi)部狀態(tài)是有限的,因此享元對象一般都設(shè)計為較小的對象,它所包含的內(nèi)部狀態(tài)較少,這種對象也稱為細(xì)粒度對象。享元模式的目的就是使用共享技術(shù)來實現(xiàn)大量細(xì)粒度對象的復(fù)用。

02.模式定義

????享元模式(Flyweight Pattern):運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度對象的復(fù)用。系統(tǒng)只使用少量的對象,而這些對象都很相似,狀態(tài)變化很小,可以實現(xiàn)對象的多次復(fù)用。由于享元模式要求能夠共享的對象必須是細(xì)粒度對象,因此它又稱為輕量級模式,它是一種對象結(jié)構(gòu)型模式。

03.模式結(jié)構(gòu)

享元模式包含如下角色:

  • Flyweight: 抽象享元類

  • ConcreteFlyweight: 具體享元類

  • UnsharedConcreteFlyweight: 非共享具體享元類

  • FlyweightFactory: 享元工廠類

04.時序圖

05.代碼示例

????我們將創(chuàng)建一個 Shape 接口和實現(xiàn)了 Shape 接口的實體類 Circle。下一步是定義工廠類 ShapeFactory。

????ShapeFactory 有一個 CircleHashMap,其中鍵名為 Circle 對象的顏色。無論何時接收到請求,都會創(chuàng)建一個特定顏色的圓。ShapeFactory 檢查它的 HashMap 中的 circle 對象,如果找到 Circle 對象,則返回該對象,否則將創(chuàng)建一個存儲在 hashmap 中以備后續(xù)使用的新對象,并把該對象返回到客戶端。

實體類:

工廠類:

06.模式分析

????享元模式是一個考慮系統(tǒng)性能的設(shè)計模式,通過使用享元模式可以節(jié)約內(nèi)存空間,提高系統(tǒng)的性能。

????享元模式的核心在于享元工廠類,享元工廠類的作用在于提供一個用于存儲享元對象的享元池,用戶需要對象時,首先從享元池中獲取,如果享元池中不存在,則創(chuàng)建一個新的享元對象返回給用戶,并在享元池中保存該新增對象。

????享元模式以共享的方式高效地支持大量的細(xì)粒度對象,享元對象能做到共享的關(guān)鍵是區(qū)分內(nèi)部狀態(tài)(Internal State)和外部狀態(tài)(External State)。

  • 內(nèi)部狀態(tài)是存儲在享元對象內(nèi)部并且不會隨環(huán)境改變而改變的狀態(tài),因此內(nèi)部狀態(tài)可以共享。

  • 外部狀態(tài)是隨環(huán)境改變而改變的、不可以共享的狀態(tài)。享元對象的外部狀態(tài)必須由客戶端保存,并在享元對象被創(chuàng)建之后,在需要使用的時候再傳入到享元對象內(nèi)部。一個外部狀態(tài)與另一個外部狀態(tài)之間是相互獨立的。

07.模式優(yōu)點

享元模式的優(yōu)點

  • 享元模式的優(yōu)點在于它可以極大減少內(nèi)存中對象的數(shù)量,使得相同對象或相似對象在內(nèi)存中只保存一份。

  • 享元模式的外部狀態(tài)相對獨立,而且不會影響其內(nèi)部狀態(tài),從而使得享元對象可以在不同的環(huán)境中被共享。

08.模式缺點

享元模式的缺點

  • 享元模式使得系統(tǒng)更加復(fù)雜,需要分離出內(nèi)部狀態(tài)和外部狀態(tài),這使得程序的邏輯復(fù)雜化。

  • 為了使對象可以共享,享元模式需要將享元對象的狀態(tài)外部化,而讀取外部狀態(tài)使得運(yùn)行時間變長。

09.模式應(yīng)用

1、JAVA 中的 String,如果有則返回,如果沒有則創(chuàng)建一個字符串保存在字符串緩存池里面。

2、數(shù)據(jù)庫的數(shù)據(jù)池。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容