享元模式
享元模式属于结构型的设计模式,其特点是运用共享技术有效地支持大量细粒度的对象。
享元模式存在内部状态和外部状态两个概念,其中内部状态是指在享元对象内部并且不会随环境改变而改变的共享部分,内部状态可以共享;外部状态是指随环境改变而改变的,取决于应用环境,或是实时数据,外部状态不可以共享。
代码
此处以开发围棋的黑棋、白棋以及棋盘以说明享元模式的好处。如果直接将每颗棋子直接存在棋盘对象中,则存在大量相似的细粒度对象(棋子),而同种颜色的棋子的区别只在位置;因此我们可以把同种颜色的棋子的位置作为外部状态来体现享元模式的好处。
C++代码
文件结构:
—include
——Piece.h
——BlackPiece.h
——WhitePiece.h
——PieceBoard.h
—src
——Piece.cpp
——BlackPiece.cpp
——WhitePiece.cpp
——PieceBoard.cpp
——main.cpp
代码如下:
—include/Piece.h
#ifndef _PIECE_H_
#define _PIECE_H_
enum PieceColor {BLACK, WHITE};
struct PiecePos
{
int x;
int y;
PiecePos(int _x, int _y);
};
class Piece
{
public:
Piece(PieceColor _color);
virtual ~Piece();
virtual void Draw()=0;
private:
PieceColor color;
};
#endif
—include/BlackPiece.h
#ifndef _BLACKPIECE_H_
#define _BLACKPIECE_H_
#include"Piece.h"
class BlackPiece:public Piece
{
public:
BlackPiece();
virtual ~BlackPiece();
virtual void Draw();
};
#endif
—include/WhitePiece.h
#ifndef _WHITEPIECE_H_
#define _WHITEPIECE_H_
#include"Piece.h"
class WhitePiece:public Piece
{
public:
WhitePiece();
virtual ~WhitePiece();
virtual void Draw();
};
#endif
—include/PieceBoard.h
#ifndef _PIECEBOARD_H_
#define _PIECEBOARD_H_
#include"Piece.h"
#include<memory>
#include<string>
#include<vector>
class PieceBoard
{
public:
PieceBoard(const std::string& bName, const std::string& wName);
~PieceBoard();
void SetPiece(const PieceColor& color, const PiecePos& piecePos);
private:
std::shared_ptr<Piece> blackPiece;
std::shared_ptr<Piece> whitePiece;
std::string blackName;
std::string whiteName;
std::vector<PiecePos> vecPiecePos;
};
#endif
—src/Piece.cpp
#include"Piece.h"
PiecePos::PiecePos(int _x, int _y):x(_x), y(_y)
{
;
}
Piece::Piece(PieceColor _color):color(_color)
{
;
}
Piece::~Piece()
{
;
}
—src/BlackPiece.cpp
#include"BlackPiece.h"
#include<iostream>
using namespace std;
BlackPiece::BlackPiece():Piece(BLACK)
{
;
}
BlackPiece::~BlackPiece()
{
;
}
void BlackPiece::Draw()
{
cout<<"绘制一只黑棋!"<<endl;
}
—src/WhitePiece.cpp
#include"WhitePiece.h"
#include<iostream>
using namespace std;
WhitePiece::WhitePiece():Piece(WHITE)
{
;
}
WhitePiece::~WhitePiece()
{
;
}
void WhitePiece::Draw()
{
cout<<"绘制一只白棋!"<<endl;
}
—src/PieceBoard.cpp
#include"PieceBoard.h"
#include"WhitePiece.h"
#include"BlackPiece.h"
#include<iostream>
using namespace std;
PieceBoard::PieceBoard(const string& bName, const string& wName):blackName(bName), whiteName(wName)
{
;
}
PieceBoard::~PieceBoard()
{
;
}
void PieceBoard::SetPiece(const PieceColor& color, const PiecePos& piecePos)
{
if(color == BLACK)
{
if(!blackPiece)
{
blackPiece = make_shared<BlackPiece>();
}
cout<<blackName<<"在位置"<<piecePos.x<<" "<<piecePos.y<<endl;
blackPiece->Draw();
}
else
{
if(!whitePiece)
{
whitePiece = make_shared<WhitePiece>();
}
cout<<whiteName<<"在位置"<<piecePos.x<<" "<<piecePos.y<<endl;
whitePiece->Draw();
}
vecPiecePos.push_back(piecePos);
}
—src/main.cpp
#include<iostream>
#include"PieceBoard.h"
#include"Piece.h"
using namespace std;
int main()
{
PieceBoard board("AlphaGo", "LiShiShi");
board.SetPiece(BLACK, PiecePos(4, 4));
board.SetPiece(WHITE, PiecePos(4, 16));
board.SetPiece(BLACK, PiecePos(16, 4));
board.SetPiece(WHITE, PiecePos(16, 16));
return 0;
}
Python代码
文件结构:
—Piece.py
—PieceBoard.py
—main.py
代码如下:
—Piece.py
# -*- coding:utf-8 -*-
from enum import Enum
PieceColor = Enum("PieceColor", ("BLACK", "WHITE"))
class PiecePos:
def __init__(self, _x, _y):
self.x = _x
self.y = _y
class Piece:
def __init__(self, color):
self.__pieceColor = color
def Draw(self):
pass
class BlackPiece(Piece):
def __init__(self):
Piece.__init__(self, PieceColor.BLACK)
def Draw(self):
print "绘制一只黑棋!"
class WhitePiece(Piece):
def __init__(self):
Piece.__init__(self, PieceColor.WHITE)
def Draw(self):
print "绘制一只白棋!"
—PieceBoard.py
# -*- coding:utf-8 -*-
from Piece import *
class PieceBoard:
def __init__(self, blackName, whiteName):
self.__blackName = blackName
self.__whiteName = whiteName
self.__blackPiece = None
self.__whitePiece = None
self.__vecPiecePos = []
def SetPiece(self, color, pos):
if (color == PieceColor.BLACK):
if(self.__blackPiece == None):
self.__blackPiece = BlackPiece()
print "%s%s%d %d"%(self.__blackName, "在位置", pos.x, pos.y)
self.__blackPiece.Draw()
else:
if(self.__whitePiece == None):
self.__whitePiece = WhitePiece()
print "%s%s%d %d"%(self.__whiteName, "在位置", pos.x, pos.y)
self.__whitePiece.Draw()
self.__vecPiecePos.append(pos)
—main.py
# -*- coding:utf-8 -*-
from PieceBoard import *
from Piece import *
if "__main__" == __name__:
board = PieceBoard("AlphaGo", "LiShiShi")
board.SetPiece(PieceColor.BLACK, PiecePos(4, 4))
board.SetPiece(PieceColor.WHITE, PiecePos(4, 16))
board.SetPiece(PieceColor.BLACK, PiecePos(16, 4))
board.SetPiece(PieceColor.WHITE, PiecePos(16, 16))