01.模式動機(jī)
享元模式正是為解決這一類問題而誕生的。享元模式通過共享技術(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.代碼示例
Shape 接口和實現(xiàn)了 Shape 接口的實體類 Circle。下一步是定義工廠類 ShapeFactory。
????ShapeFactory 有一個 Circle 的 HashMap,其中鍵名為 Circle 對象的顏色。無論何時接收到請求,都會創(chuàng)建一個特定顏色的圓。ShapeFactory 檢查它的 HashMap 中的 circle 對象,如果找到 Circle 對象,則返回該對象,否則將創(chuàng)建一個存儲在 hashmap 中以備后續(xù)使用的新對象,并把該對象返回到客戶端。
實體類:
工廠類:
06.模式分析
????享元模式的核心在于享元工廠類,享元工廠類的作用在于提供一個用于存儲享元對象的享元池,用戶需要對象時,首先從享元池中獲取,如果享元池中不存在,則創(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)點在于它可以極大減少內(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)用
2、數(shù)據(jù)庫的數(shù)據(jù)池。