每天一个设计模式之享元模式 Qt系列教程

  • A+
所属分类:Qt系列教程

介绍

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则先创建新对象再使用。

意图:运用共享技术有效地支持大量细粒度的对象。

主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。

何时使用: 1、系统中有大量对象。 2、这些对象消耗大量内存。 3、这些对象的状态大部分可以外部化。 4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。 5、系统不依赖于这些对象身份,这些对象是不可分辨的。

如何解决:用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象。

关键代码:用 HashMap 存储这些对象。

应用实例: 1、JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。 2、数据库的数据池。

优点:大大减少对象的创建,降低系统的内存,使效率提高。

缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。

使用场景: 1、系统有大量相似对象。 2、需要缓冲池的场景。

注意事项: 1、注意划分外部状态和内部状态,否则可能会引起线程安全问题。 2、这些类必须有一个工厂对象加以控制。

代码

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. using namespace std;
  5. //棋子的颜色
  6. enum PieceColor{BLACK,WHITE};
  7. //棋子的位置
  8. struct PiecePos
  9. {
  10.     int m_x;
  11.     int m_y;
  12.     PiecePos(int a,int b):m_x(a),m_y(b) {}
  13. };
  14. class Piece{
  15. protected:
  16.     PieceColor m_color;
  17. public:
  18.     Piece(PieceColor color)
  19.         :m_color(color)
  20.     {
  21.     }
  22.     ~Piece(){}
  23.     virtual void draw(){}
  24. };
  25. class BlackPiece:public Piece{
  26. public:
  27.     BlackPiece(PieceColor color):Piece(color)
  28.     {
  29.     }
  30.     ~BlackPiece(){}
  31.     void draw(){cout<<"draw a black piece"<<endl;}
  32. };
  33. class WhitePiece:public Piece{
  34. public:
  35.     WhitePiece(PieceColor color):Piece(color)
  36.     {
  37.     }
  38.     ~WhitePiece(){}
  39.     void draw(){cout<<"draw a white piece"<<endl;}
  40. };
  41. class PieceBoard{
  42. public:
  43.     PieceBoard(string black,string white)
  44.         :m_blackName(black)
  45.         ,m_whiteName(white)
  46.         ,m_pBlackPiece(NULL)
  47.         ,m_pWhitePiece(NULL){}
  48.     ~PieceBoard(){
  49.         clear();
  50.     }
  51.     void clear()
  52.     {
  53.         delete m_pWhitePiece;
  54.         delete m_pBlackPiece;
  55.     }
  56.     void setPiece(PieceColor color,PiecePos pos){
  57.         if(color == BLACK)
  58.         {
  59.             if(!m_pBlackPiece)
  60.             {
  61.                 m_pBlackPiece = new BlackPiece(color);
  62.             }
  63.             cout<<m_blackName<<" add one black piece at "<<pos.m_x<<","<<pos.m_y<<endl;
  64.             m_pBlackPiece->draw();
  65.         }
  66.         else{
  67.             if(!m_pWhitePiece)
  68.             {
  69.                 m_pWhitePiece = new WhitePiece(color);
  70.             }
  71.             cout<<m_whiteName<<" add one white piece at "<<pos.m_x<<","<<pos.m_y<<endl;
  72.             m_pWhitePiece->draw();
  73.         }
  74.         m_vecPiece.push_back(pos);
  75.     }
  76. private:
  77.     vector<PiecePos> m_vecPiece;//棋盘上的棋子
  78.     string m_blackName;
  79.     string m_whiteName;
  80.     //这里就是享元模式的体现,绘制棋谱时并没有保存所有的棋子,
  81.     //而是只创建了两个黑白棋子对象,每次绘制时复用对象的draw函数
  82.     //享元模式关注的是复用对象中的方法,当我们只需要使用对象中的方法,
  83.     //不需要存储成员变量时,或者方法需要的数据可以通过形参传入
  84.     //为了控制内存占用,可以使用享元模式(最终结果是减少了内存占用)
  85.     //与原型模式不同的是,原型模式解决的是创建对象代价大的问题(如需要访问数据库才能完成对象创建)
  86.     //当然普通的做法是创建棋谱中所有的棋子对象,每个棋子都调用该对象的draw函数
  87.     //这样做会创建大量对象,小型机上容易造成内存溢出
  88.     Piece* m_pBlackPiece;
  89.     Piece* m_pWhitePiece;
  90. };
  91. int main(){
  92.     PieceBoard pieceBoard("laoxia","laoding");
  93.     pieceBoard.setPiece(BLACK,PiecePos(44,37));
  94.     pieceBoard.setPiece(WHITE,PiecePos(46,33));
  95.     pieceBoard.setPiece(BLACK,PiecePos(45,38));
  96.     pieceBoard.setPiece(WHITE,PiecePos(44,33));
  97.     system("pause");
  98.     return 0;
  99. }

 

Qt大课堂-QtShare

发表评论

您必须登录才能发表评论!