您的当前位置:首页正文

c++享元模式

2024-11-26 来源:个人技术集锦

享元模式

1、享元模式简介

  享元模式在《设计模式:可复用面向对象软件的基础》一书中是这样说的:运用共享技术有效地支持大量细粒度的对象。本质就是对大量细粒度的对象进行共享,不是每个对象都要通过new的方式去创建,而是通过区分对象的内部状态和外部状态来实现共享。以此来达到减少系统的开销,提高程序性能的目的。

2、应用场景

  在某个类在系统中有大量的实例时,并且可根据这些实例的特征分离出内部状态可外部状态。

3、实例讲解

  以五子棋为例,常规情况如果每下一颗棋就去new一个对象的话。会造成大量重复的系统开销。影响系统性能,显然这种方式是不必要的。那么我们可以使用享元模式来解决此类问题。可以在棋子中抽象出内部状态可外部状态,棋子的属性无非是颜色和位置,颜色非黑即白我们可以作为内部状态,由棋子类的对象来维护,棋子的位置如果也为内部状态,且每颗棋子的位置都是不同的,那每颗棋子仍然是要通过new的方式来构建棋子对象。故棋子的位置要作为外部状态,不在棋子的内部进行维护,而是由上层调用棋子处维护。如此便区分了内部和外部状态,以下代码示例:

3.1、棋子类实现

//棋子颜色
enum PieceColor {BLACK, WHITE};
//棋子位置
struct PiecePos
{
	int x;
	int y;
	PiecePos(int a, int b): x(a), y(b) {}
};
//棋子定义
class Piece
{
protected:
	PieceColor m_color; //颜色
public:
	Piece(PieceColor color): m_color(color) {}
	~Piece() {}
	virtual void Draw() {}
};
class BlackPiece: public Piece
{
public:
	BlackPiece(PieceColor color): Piece(color) {}
	~BlackPiece() {}
	void Draw() { cout<<"绘制一颗黑棋\n"; }
};
class WhitePiece: public Piece
{
public:
	WhitePiece(PieceColor color): Piece(color) {}
	~WhitePiece() {}
	void Draw() { cout<<"绘制一颗白棋\n";}
};

3.2、棋盘类实现

class PieceBoard
{
private:
	vector<PiecePos> m_vecPos; //存放棋子的位置
	Piece *m_blackPiece;       //黑棋棋子 
	Piece *m_whitePiece;       //白棋棋子
	string m_blackName;
	string m_whiteName;
public:
	PieceBoard(string black, string white): m_blackName(black), m_whiteName(white)
	{
		m_blackPiece = NULL;
		m_whitePiece = NULL;
	}
	~PieceBoard() { delete m_blackPiece; delete m_whitePiece;}
	void SetPiece(PieceColor color, PiecePos pos)
	{
		if(color == BLACK)
		{
			if(m_blackPiece == NULL)  //只有一颗黑棋
				m_blackPiece = new BlackPiece(color);	
			cout<<m_blackName<<"在位置("<<pos.x<<','<<pos.y<<")";
			m_blackPiece->Draw();
		}
		else
		{
			if(m_whitePiece == NULL)
				m_whitePiece = new WhitePiece(color);
			cout<<m_whiteName<<"在位置("<<pos.x<<','<<pos.y<<")";
			m_whitePiece->Draw();
		}
		m_vecPos.push_back(pos);
	}
};

3.3、 客户端调用:

int main()
{
	PieceBoard pieceBoard("A","B");
	pieceBoard.SetPiece(BLACK, PiecePos(4, 4));
	pieceBoard.SetPiece(WHITE, PiecePos(4, 16));
	pieceBoard.SetPiece(BLACK, PiecePos(16, 4));
	pieceBoard.SetPiece(WHITE, PiecePos(16, 16));
}
显示全文