一、概述
享元模式(Flyweight),就是利用共享技術有效地支持大量細粒度的對象。
當程序創建大量的對象時有損程序的性能,同時還容易造成內存溢出。我們將對象內部的信息進行細粒度地劃分,將一部分信息提取出來進行共享,可以節省內存空間,提高程序性能。對象細粒度化後的信息分爲兩個部分:內部狀態(intrinsic)與外部狀態(extrinsic)。內部狀態是對象可以共享出來的信息,存儲在享元對象內部,並且不會隨着環境改變而改變。外部狀態是隨着環境改變而改變的,不可以共享的信息,存儲在對象的外面,一般由客戶端對象存儲,當調用享元對象的操作時,將外部狀態傳遞給享元對象。
二、享元模式的類圖
三、實例
//象棋內部狀態參數,總共2*11=22種,不會隨着環境改變而改變
class ChessIntrisicState
{
public:
//1:紅,2:黑;總共兩種
int nColorType;
//棋子名稱:帥,將,車,炮,馬,相,象,仕,士,兵,卒;總共11種
int nChessPieceName;
};
//象棋外部狀態參數,隨着環境改變而改變
class ChessExtrisicState
{
public:
int nXPos;
int nYPos;
};
//棋子基類,對應享元基類Flyweight
class AbstractChess
{
public:
//享元類具體操作時除了需要內部狀態參數,可能還需要外部狀態參數
virtual void Play(ChessExtrisicState objExState);
};
//棋子類,對應ConcreteFlyweight
class Chess : public AbstractChess
{
public:
Chess (ChessIntrisicState objInState)
{
m_objInState = objInState;
}
virtual void Play(ChessExtrisicState objExState);
private:
//內部狀態參數
ChessIntrisicState m_objInState;
};
void Play(ChessExtrisicState objExState)
{
cout<<"象棋顏色:"<<m_objInState.nColorType<<",名稱:"<<m_objInState.nChessPieceName<<",在位置:"<<objExState.nXPos<<"-"<<objExState.nYPos<<endl;
}
//對應UnsharedConcreteFlyweight,爲不需要共享的享元子類,由上層用戶創建並維護
class UnsharedChess
{
public:
virtual void Play(ChessExtrisicState objExState);
private:
int m_nAllState;
};
//享元工廠類,對應FlyweightFactory
class ChessFactory
{
public:
//獲取享元對象,如果已經有了則直接返回已有的享元對象,如果沒有則新建一個享元對象
Chess* GetChess(ChessIntrisicState objKey);
private:
map<ChessIntrisicState ,Chess*> m_mapChessList;
};
Chess* ChessFactory::GetChess(ChessIntrisicState objKey)
{
map<int,Chess*>::iterator it = m_mapChessList.find(objKey);
if(it != m_mapChessList.end())
{
return it->second;
}
else
{
Chess* pChess = new ConcreteFlyweight(nKey);
m_mapChessList[nKey] = pFlyweight;
return pFlyweight;
}
}
int main()
{
FlyweightFactory* pFactory = new FlyweightFactory();
Flyweight f1 = pFactory->GetFlyweight(1);
}