设计模式——享元
目的和动机
运用共享技术有效地支持大量地细粒度对象。
享:代表共享;
元:基本单元
关键概念:内部状态和外部状态
场景
以下情况都成立时方可使用:
- 一个应用程序使用了大量地对象
- 大量地对象造成了存储开销
- 对象地大多数状态可变为外部状态
- 删除对象地外部状态,可以使用相对较少地共享对象取代很多组对象
- 应用程序不依赖于对象表示
例如文档编辑器和棋盘
UML
实现
#include <iostream> #include <vector> using namespace std; 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; PiecePos m_pos; public: Piece(PieceColor color, PiecePos pos):m_color(color),m_pos(pos) { } ~Piece(){} virtual void draw(){} void showPos() { cout << "pos is:("<<m_pos.x <<","<<m_pos.y<<")."<<endl; } }; class BlackPiece : public Piece { public: BlackPiece(PieceColor color, PiecePos pos):Piece(color, pos) { } ~BlackPiece(){} void draw() { cout << "draw black piece" <<endl; } }; class WhitePiece : public Piece { public: WhitePiece(PieceColor color, PiecePos pos):Piece(color, pos) { } ~WhitePiece(){} void draw() { cout << "draw white piece" <<endl; } }; class PieceBorad { private: vector<Piece*> m_vecPiece; string m_blaceName; string m_whiteName; public: PieceBorad(string black, string white):m_blaceName(black),m_whiteName(white) { } ~PieceBorad() { for(auto item : m_vecPiece) { delete item; } } void setPiece(PieceColor color, PiecePos pos) { Piece* piece = nullptr; if(color == BLACK) { piece = new BlackPiece(color ,pos); cout<<m_blaceName << " "; } else { piece = new WhitePiece(color ,pos); cout<<m_whiteName << " "; } piece->showPos(); piece->draw(); m_vecPiece.push_back(piece); } }; int main() { PieceBorad 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)); getchar(); cout << endl; return 0; }
优缺点
缺点:使用享元模式时,查找,传输,计算外部状态都会产生运行时的开销,尤其当享元原先被存储为内部状态时
优点:节省了内存存储开销,共享的flyweight越多,空间节省越大。原因时实例总数目减少,对象地内部状态地平均数目,外部状态时计算还是存储。
即以时间换空间
注意事项
1 删除外部状态 :此设计模式的可用性取决于是都容易识别外部状态,并将其从共享对象中删除
2 管理共享对象 对象是共享的,用户不能直接对其进行实例化,需要通过享元工厂查找具体的享元对象。共享还意味这某种形式的引用计数和垃圾回收,即一个对象不在使用时,可以回收其存储空间
一般和组合模式使用