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

  • 相关阅读:
    Java 8 Lambda 表达式
    OSGi 系列(十二)之 Http Service
    OSGi 系列(十三)之 Configuration Admin Service
    OSGi 系列(十四)之 Event Admin Service
    OSGi 系列(十六)之 JDBC Service
    OSGi 系列(十)之 Blueprint
    OSGi 系列(七)之服务的监听、跟踪、声明等
    OSGi 系列(六)之服务的使用
    OSGi 系列(三)之 bundle 事件监听
    OSGi 系列(三)之 bundle 详解
  • 原文地址:https://www.cnblogs.com/jeakeven/p/4966965.html
Copyright © 2011-2022 走看看