享元模式
享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。
围棋游戏与享元模式
说道享元模式,最经典的例子就是围棋了,我们都知道,围棋中有许多棋子,每个棋子都有它们各自的信息:
enum PieceColor{BLACK,WHITE};
string ColorStr[2] = {"black","white"};
struct Point
{
int x;
int y;
Point(int x_,int y_):x(x_),y(y_) {}
};
class Piece//棋子信息
{
public:
Piece(Point point,PieceColor color):m_point(point),m_color(color) {}
void Draw() {cout << "draw " << ColorStr[m_color] << " at(" << m_point.x << "," << m_point.y << ")" << endl;}
protected:
Point m_point;
PieceColor m_color;
};
现在让棋盘来保存这些信息:
class PieceBoard
{
public:
PieceBoard(){}
~PieceBoard(){Clear();}
void SetPiece(PieceColor color, Point pos)//放置一个棋子
{
Piece * piece = NULL;
if(color == BLACK)//黑棋
{
piece = new Piece(color, pos);
cout << "set black at("<<pos.x<<','<<pos.y<<")" << endl;
piece->Draw();
}
else//白棋
{
piece = new Piece(color, pos);
cout << "set white at("<<pos.x<<','<<pos.y<<")" << endl;
piece->Draw();
}
m_Piece.push_back(piece);//储存信息
}
void Clear()
{
int size = m_Piece.size();
for(int i = 0; i < size; i++)
delete m_Piece[i];
}
private:
vector<Piece*> m_Piece;
};
现在我们可以往我们的棋盘里下棋了,而棋盘会记住我们下的棋子,但是它会详细的记录每一个棋子的全部信息,这在棋子非常多的情况下会非常占用资源。
于是我们发现对一个棋子而言,其内在的属性只有颜色,而位置是其外在的属性,所以我们使用享元模式,让其共享内在的属性。
enum PieceColor{BLACK,WHITE};
string ColorStr[2] = {"black","white"};
struct Point
{
int x;
int y;
Point(int x_, int y_):x(x_),y(y_) {}
};
class Piece
{
public:
Piece(PieceColor color):m_color(color){}
void Draw(Point point) {cout << "draw " << ColorStr[m_color] << " at(" << point.x << "," << point.y << ")" << endl;}
protected:
PieceColor m_color;//现在无需记录位置信息
};
class PieceBoard
{
public:
PieceBoard():m_BlackPiece(NULL),m_WhitePiece(NULL) {}
~PieceBoard(){}
void SetPiece(PieceColor color, Point pos)
{
if(color == BLACK)
{
if(m_BlackPiece == NULL)
m_BlackPiece = new Piece(color);
cout << "set black at("<<pos.x<<','<<pos.y<<")" << endl;
m_BlackPiece->Draw(pos);
m_BlackPoint.push_back(pos);
}
else
{
if(m_WhitePiece == NULL)
m_WhitePiece = new Piece(color);
cout << "set white at("<<pos.x<<','<<pos.y<<")" << endl;
m_WhitePiece->Draw(pos);
m_WhitePoint.push_back(pos);
}
}
private:
vector<Point> m_BlackPoint;
vector<Point> m_WhitePoint;
Piece *m_BlackPiece;//
Piece *m_WhitePiece;//被共享的棋子
};
这样棋盘中之创建了两个棋子对象就完成了相同的功能