实验13:享元模式

发布时间 2023-12-09 20:15:14作者: 林浅

本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:

1、理解享元模式的动机,掌握该模式的结构;

2、能够利用享元模式解决实际问题。

 

[实验任务一]:围棋

设计一个围棋软件,在系统中只存在一个白棋对象和一个黑棋对象,但是它们可以在棋盘的不同位置显示多次。

实验要求:

1. 提交类图;

2.提交源代码;

3.注意编程规范;

4.要求用简单工厂模式和单例模式实现享元工厂类的设计

#include <iostream>

#include <map>

#include <vector>

using namespace std;

 

typedef struct Coordinates

{

    int x;

    int y;

 

    Coordinates(){}

    Coordinates(int a, int b){x=a;y=b;}

 

    bool operator <(const Coordinates& other) const

    {

        if (x<other.x) return true;

        else if (x==other.x) return y<other.y;

        return false;

    }

}POINT;

 

typedef enum PieceColorTag

{

    BLACK,

    WHITE

}PIECECOLOR;

 

class CPiece

{

public:

    CPiece(PIECECOLOR color) : m_color(color){}

    PIECECOLOR GetColor() { return m_color; }

 

    // Set the external state

    void SetPoint(POINT point) { m_point = point; }

    POINT GetPoint() { return m_point; }

 

protected:

    // Internal state

    PIECECOLOR m_color;

 

    // external state

    POINT m_point;

};

 

class CGomoku : public CPiece

{

public:

    CGomoku(PIECECOLOR color) : CPiece(color){}

};

 

class IgoChessmanFactory

{

public:

    CPiece *GetPiece(PIECECOLOR color)

    {

        CPiece *pPiece = NULL;

    if (m_vecPiece.empty())

    {

        pPiece = new CGomoku(color);

        m_vecPiece.push_back(pPiece);

    }

    else

    {

        for (vector<CPiece *>::iterator it = m_vecPiece.begin(); it != m_vecPiece.end(); ++it)

        {

            if ((*it)->GetColor() == color)

        {

            pPiece = *it;

            break;

        }

        }

        if (pPiece == NULL)

        {

        pPiece = new CGomoku(color);

        m_vecPiece.push_back(pPiece);

        }

     }

        return pPiece;

    }

 

    ~IgoChessmanFactory()

    {

        for (vector<CPiece *>::iterator it = m_vecPiece.begin(); it != m_vecPiece.end(); ++it)

        {

            if (*it != NULL)

        {

        delete *it;

        *it = NULL;

        }

    }

    }

 

private:

    vector<CPiece *> m_vecPiece;

};

 

class IgoChessman

{

public:

    void Draw(CPiece *piece)

    {

    if (piece->GetColor())

    {

            cout<<"Draw a White"<<" at ("<<piece->GetPoint().x<<","<<piece->GetPoint().y<<")"<<endl;

    }

    else

    {

        cout<<"Draw a Black"<<" at ("<<piece->GetPoint().x<<","<<piece->GetPoint().y<<")"<<endl;

    }

    m_mapPieces.insert(pair<POINT, CPiece *>(piece->GetPoint(), piece));

    }

 

    void ShowAllPieces()

    {

        for (map<POINT, CPiece *>::iterator it = m_mapPieces.begin(); it != m_mapPieces.end(); ++it)

    {

            if (it->second->GetColor())

        {

        cout<<"("<<it->first.x<<","<<it->first.y<<") has a White chese."<<endl;

        }

        else

        {

        cout<<"("<<it->first.x<<","<<it->first.y<<") has a Black chese."<<endl;

        }

    }

    }

 

private:

    map<POINT, CPiece *> m_mapPieces;

};

 

int main()

{

    IgoChessmanFactory *pPieceFactory = new IgoChessmanFactory();

    IgoChessman *pCheseboard = new IgoChessman();

 

    // The player1 get a white piece from the pieces bowl

    CPiece *pPiece = pPieceFactory->GetPiece(WHITE);

    pPiece->SetPoint(POINT(2, 3));

    pCheseboard->Draw(pPiece);

 

    // The player2 get a black piece from the pieces bowl

    pPiece = pPieceFactory->GetPiece(BLACK);

    pPiece->SetPoint(POINT(4, 5));

    pCheseboard->Draw(pPiece);

 

    // The player1 get a white piece from the pieces bowl

    pPiece = pPieceFactory->GetPiece(WHITE);

    pPiece->SetPoint(POINT(2, 4));

    pCheseboard->Draw(pPiece);

 

    // The player2 get a black piece from the pieces bowl

    pPiece = pPieceFactory->GetPiece(BLACK);

    pPiece->SetPoint(POINT(3, 5));

    pCheseboard->Draw(pPiece);

}