设计模式 共享模式

看了果冻兄的博客,发现大家对里面的一个实现有一些不同的见解,贴出来记录一下,其博文如下

http://www.jellythink.com/archives/295

共享模式的主要想法就是:运用共享技术有效地支持大量细粒度的对象。所以应该将对象的外部特征由更高一级的对象来管理。在原文中,博主将棋子的外部特征(坐标)作为了棋子的一个属性来管理,又在棋盘类中采用覆盖的方法来每一次添加共享模式棋子时,刷新其坐标,再记录之。感觉刷新的这一步有点多余,所以我去掉了棋子的坐标属性,直接在记录时添加了坐标信息。不过这样做的缺点就是,坐标属性在类的实现中体现的不够明显,是否有违设计的原则呢?后面再查查资料,或者如有大神看到,还望解答。

代码分别如下:

果冻兄代码:

#include <iostream>
#include <map>
#include <vector>
using namespace std;

typedef struct pointTag
{
    int x;
    int y;

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

    bool operator <(const pointTag& 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 CPieceFactory
{
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;
    }    

    ~CPieceFactory()
    {
        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 CChessboard
{
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()
{
    CPieceFactory *pPieceFactory = new CPieceFactory();
    CChessboard *pCheseboard = new CChessboard();

    // 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);

    /*......*/

    //Show all cheses
    cout<<"Show all cheses"<<endl;
    pCheseboard->ShowAllPieces();

    if (pCheseboard != NULL)
    {
 	delete pCheseboard;
	pCheseboard = NULL;
    }
    if (pPieceFactory != NULL)
    {
	delete pPieceFactory;
	pPieceFactory = NULL;
    }
}

我改了后的:

...

class CPiece
{
public:
    CPiece(PIECECOLOR color) : m_color(color){}
    PIECECOLOR GetColor() { return m_color; }

protected:
    // Internal state
    PIECECOLOR m_color;

};

class CGomoku : public CPiece
{
public:
    CGomoku(PIECECOLOR color) : CPiece(color){}
};

class CPieceFactory
{
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;
    }    

    ~CPieceFactory()
    {
        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 CChessboard
{
public:
    void Draw(CPiece *piece, POINT point)
    {
	if (piece->GetColor())
	{
            cout<<"Draw a White"<<" at ("<<point.x<<","<<point.y<<")"<<endl;
	}
	else
	{
	    cout<<"Draw a Black"<<" at ("<<point.x<<","<<point.y<<")"<<endl;
	}
	m_mapPieces.insert(pair<POINT, CPiece *>(point, 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()
{
    CPieceFactory *pPieceFactory = new CPieceFactory();
    CChessboard *pCheseboard = new CChessboard();

    // The player1 get a white piece from the pieces bowl
    CPiece *pPiece = pPieceFactory->GetPiece(WHITE);
    pCheseboard->Draw(pPiece,POINT(2, 3));

    // The player2 get a black piece from the pieces bowl
    pPiece = pPieceFactory->GetPiece(BLACK);
    pCheseboard->Draw(pPiece,POINT(4, 5));

    // The player1 get a white piece from the pieces bowl
    pPiece = pPieceFactory->GetPiece(WHITE);
    pCheseboard->Draw(pPiece,POINT(2, 4));

    // The player2 get a black piece from the pieces bowl
    pPiece = pPieceFactory->GetPiece(BLACK);
    pCheseboard->Draw(pPiece,POINT(3, 5));

    /*......*/

    ...
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值