設計模式--享元模式Flyweight(對象結構型)

一、概述

享元模式(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);
    
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章