设计模式——享元

 

这里写自定义目录标题

 

目的和动机

运用共享技术有效地支持大量地细粒度对象。
享:代表共享;
元:基本单元
关键概念:内部状态和外部状态

场景

以下情况都成立时方可使用:

  1. 一个应用程序使用了大量地对象
  2. 大量地对象造成了存储开销
  3. 对象地大多数状态可变为外部状态
  4. 删除对象地外部状态,可以使用相对较少地共享对象取代很多组对象
  5. 应用程序不依赖于对象表示

例如文档编辑器和棋盘

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;
}
View Code

 

优缺点

缺点:使用享元模式时,查找,传输,计算外部状态都会产生运行时的开销,尤其当享元原先被存储为内部状态时
优点:节省了内存存储开销,共享的flyweight越多,空间节省越大。原因时实例总数目减少,对象地内部状态地平均数目,外部状态时计算还是存储。
即以时间换空间

注意事项

1 删除外部状态 :此设计模式的可用性取决于是都容易识别外部状态,并将其从共享对象中删除
2 管理共享对象 对象是共享的,用户不能直接对其进行实例化,需要通过享元工厂查找具体的享元对象。共享还意味这某种形式的引用计数和垃圾回收,即一个对象不在使用时,可以回收其存储空间

一般和组合模式使用

 

posted @ 2021-09-28 08:56  Kiris  阅读(28)  评论(0编辑  收藏  举报