享元模式——運用共享技術有效地支持大量細粒度的對象。享元模式可以避免大量相似類的開銷,在軟件開發(fā)中如果需要生成大量細粒度的類實例來表示數(shù)據(jù),如果這些實例除了幾個參數(shù)外基本上都是相同的,這時候就可以使用享元模式來大幅度減少需要實例化類的數(shù)量
享元模式的類圖
抽象享元角色(Flyweight):此角色是所有的具體享元類的基類,為這些類規(guī)定出需要實現(xiàn)的公共接口。那些需要外部狀態(tài)的操作可以通過調(diào)用方法以參數(shù)形式傳入
具體享元角色(ConcreteFlyweight):實現(xiàn)抽象享元角色所規(guī)定的接口。如果有內(nèi)部狀態(tài)的話,可以在類內(nèi)部定義
享元工廠角色(FlyweightFactory):本角色復雜創(chuàng)建和管理享元角色。本角色必須保證享元對象可以被系統(tǒng)適當?shù)毓蚕恚斠粋€客戶端對象調(diào)用一個享元對象的時候,享元工廠角色檢查系統(tǒng)中是否已經(jīng)有一個符合要求的享元對象,如果已經(jīng)存在,享元工廠角色就提供已存在的享元對象,如果系統(tǒng)中沒有一個符合的享元對象的話,享元工廠角色就應當創(chuàng)建一個合適的享元對象
-
客戶端角色(Client):本角色需要存儲所有享元對象的外部狀態(tài)
例如Tile保存x, y等特有的變量外還有保存Mesh等可共用的變量
class MeshFactory
{
static map<string, Mesh*> meshs;
public:
static Mesh* getMesh(string key)
{
map<string, Mesh*>::iterator iter = meshs.find(key);
if (iter != meshs.end())
{
return iter->second;
}
Mesh *mesh = new ConcreteMesh(key);
meshs.insert(pair<string, Mesh*>(key, mesh));
return mesh;
}
static int getSum()
{
return meshs.size();
}
};
map<string, Mesh*> MeshFactory::meshs;
享元模式的核心在于享元工廠類,享元工廠類的作用在于提供一個用于存儲享元對象的享元池,用戶需要對象時,首先從享元池中獲取,如果享元池中不存在,則創(chuàng)建一個新的享元對象返回給用戶,并在享元池中保存該新增對象
享元模式的優(yōu)缺點
分析完享元模式的實現(xiàn)之后,讓我們繼續(xù)分析下享元模式的優(yōu)缺點:
優(yōu)點:
- 降低了系統(tǒng)中對象的數(shù)量,從而降低了系統(tǒng)中細粒度對象給內(nèi)存帶來的壓力
缺點:
- 為了使對象可以共享,需要將一些狀態(tài)外部化,這使得程序的邏輯更復雜,使系統(tǒng)復雜化
- 享元模式將享元對象的狀態(tài)外部化,而讀取外部狀態(tài)使得運行時間稍微變長
總結
到這里,享元模式的介紹就結束了,享元模式主要用來解決由于大量的細粒度對象所造成的內(nèi)存開銷的問題,它在實際的開發(fā)中并不常用,可以作為底層的提升性能的一種手段