zoukankan      html  css  js  c++  java
  • 设计模式 --> (10)享元模式

    享元模式

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

      享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External State)。

      内蕴状态是存储在享元对象内部并且不会随环境改变而改变。因此内蕴状态并可以共享。

      外蕴状态是随环境改变而改变的、不可以共享的状态。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外蕴状态与内蕴状态是相互独立的。

    适用性:

      1.当系统中有大量的细粒度对象实例,而且这些对象实例中有一些属性是重复的情况下,考虑使用。

      2.文本编辑器,输入法之类的常用应用。

    优点:

      1.提高了系统的效率,减小了内存的消耗。

      2.减少了重复代码。

      3.减少了系统的复杂度。

    缺点:

      1.维护共享对象和查找所需的共享对象需要花费很多时间。

    举例

      举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子。现在要实现一个围棋程序,该怎么办呢?首先要考虑的是棋子棋盘的实现,可以定义一个棋子的类,成员变量包括棋子的颜色、形状、位置等信息,另外再定义一个棋盘的类,成员变量中有个容器,用于存放棋子的对象。

      在围棋中,棋子就是大量细粒度的对象。其属性有内在的,比如颜色、形状等,也有外在的,比如 在棋盘上的位置。内在的属性是可以共享的,区分在于外在属性。因此,可以这样设计,只需定义两个棋子的对象,一颗黑棋和一颗白棋,这两个对象含棋子的内在 属性;棋子的外在属性,即在棋盘上的位置可以提取出来,存放在单独的容器中。相比之前的方案,现在容器中仅仅存放了位置属性,而原来则是棋子对象。显然, 现在的方案大大减少了对于空间的需求。

    #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; //颜色  
    public:  
        Piece(PieceColor color): m_color(color) {}  
        ~Piece() {}  
        virtual void Draw() {}  
    };  
    
    //黑棋 
    class BlackPiece: public Piece  
    {  
    public:  
        BlackPiece(PieceColor color): Piece(color) {}  
        ~BlackPiece() {}  
        void Draw() { cout<<"绘制一颗黑棋
    "; }  
    };  
    
    //白棋 
    class WhitePiece: public Piece  
    {  
    public:  
        WhitePiece(PieceColor color): Piece(color) {}  
        ~WhitePiece() {}  
        void Draw() { cout<<"绘制一颗白棋
    ";}  
    };  
    
    //棋盘 
    class PieceBoard  
    {  
    private:  
        vector<PiecePos> m_vecPos; //存放棋子的位置  
        Piece *m_blackPiece;       //黑棋棋子   
        Piece *m_whitePiece;       //白棋棋子  
        string m_blackName;  
        string m_whiteName;  
    public:  
        PieceBoard(string black, string white): m_blackName(black), m_whiteName(white)  
        {  
            m_blackPiece = NULL;  
            m_whitePiece = NULL;  
        }  
        ~PieceBoard() { delete m_blackPiece; delete m_whitePiece;}  
        void SetPiece(PieceColor color, PiecePos pos)  
        {  
            if(color == BLACK)  
            {  
                if(m_blackPiece == NULL)  //只有一颗黑棋  
                    m_blackPiece = new BlackPiece(color);     
                cout<<m_blackName<<"在位置("<<pos.x<<','<<pos.y<<")";  
                m_blackPiece->Draw();  
            }  
            else  
            {  
                if(m_whitePiece == NULL)  
                    m_whitePiece = new WhitePiece(color);  
                cout<<m_whiteName<<"在位置("<<pos.x<<','<<pos.y<<")";  
                m_whitePiece->Draw();  
            }  
            m_vecPos.push_back(pos);  
        }  
    };
    
    int main()  
    {  
        PieceBoard 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));  
    }   

    参考 http://blog.csdn.net/wuzhekai1985

  • 相关阅读:
    Struts2框架复习(一)--最基本的struts2框架
    CentOS7安装MariaDB成功的实践
    Visual Studio 2015 配置 Python 环境
    使用 Visual Studio 2015 + Python3.6 + tensorflow 构建神经网络时报错:'utf-8' codec can't decode byte 0xcc in position 78: invalid continuation byte
    C++解析Json,使用JsonCpp读写Json数据
    【CMake】CMake ERROR:could not find git for clone of
    【CMake】CMake GUI构建VS等项目
    SPH液面重构过程中的问题
    SPH流体模拟及液面重构问题
    mybatis级联查询,多对一查询问题
  • 原文地址:https://www.cnblogs.com/jeakeven/p/4966965.html
Copyright © 2011-2022 走看看