zoukankan      html  css  js  c++  java
  • 享元模式(c++实现)

    享元模式

    模式定义

    享元模式(Flyweight),运用共享技术有效的支持大量细粒度的对象。

    模式动机

    • 如果一个应用使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用。
    • 当对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享内存对象取代很多组对象,此时可以考虑使用享元模式。

    UML类图

    源码实现

    • piece.h
    #include <string>
    enum Color
    {
        white,
        black
    };
    class Piece
    {
    public:
        Piece(Color color);
        void setPoint(int x, int y);
        Color GetColor() const;
    public:
        int     m_X;
        int     m_Y;
    
    private:
        Color     m_Color;
    };
    
    • piece.cpp
    #include "piece.h"
    
    Piece::Piece(Color color)
        :m_Color(color)
    {
    
    }
    
    void Piece::setPoint(int x, int y)
    {
        m_X = x;
        m_Y = y;
    }
    
    Color Piece::GetColor() const
    {
        return m_Color;
    }
    
    • checkerboard.h
    #include <string>
    #include "piece.h"
    class CheckerBoard
    {
    public:
        CheckerBoard();
        void Draw();
        void refresh();
        void GetPiece(const Piece& piece);
    
    private:
        std::string     m_Checker;
    };
    
    • checkerboard.cpp
    #include <iostream>
    #include <string.h>
    #include "checkerboard.h"
    
    CheckerBoard::CheckerBoard()
    {
        for(int m = 0; m < 20; ++m)
        {
            for(int n = 0; n < 20; ++n)
                m_Checker.append("o");
            m_Checker.append("
    ");
        }
    }
    
    void CheckerBoard::Draw()
    {
        std::cout << m_Checker;
    }
    
    void CheckerBoard::refresh()
    {
        system("cls");
        std::cout << m_Checker;
    }
    
    void CheckerBoard::GetPiece(const Piece& piece)
    {
        int pos;
        pos = (piece.m_Y * 21) + piece.m_X;
    
        if(piece.GetColor() == Color::white)
            m_Checker.replace(pos, 1, "-");
        else if(piece.GetColor() == Color::black)
            m_Checker.replace(pos, 1, "+");
    }
    
    • piecefactory.h
    #include <map>
    #include "piece.h"
    class PieceFactory
    {
    public:
        PieceFactory();
        Piece *find(Color color);
    private:
        std::map<Color, Piece*>     m_PiecesMap;
    };
    
    • piecefactory.cpp
    #include <memory>
    #include "piecefactory.h"
    
    PieceFactory::PieceFactory()
    {
    
    }
    
    Piece *PieceFactory::find(Color color)
    {
        auto piece = m_PiecesMap.find(color);
        if(piece != m_PiecesMap.end()){
            return piece->second;
        }
        else
        {
            Piece* p = new Piece(color);
            m_PiecesMap[color] = p;
            return p;
        }
    }
    
    
    • main.cpp
    /************************************
        * @brief	: 享元模式
        * @author	:   wzx
        * @date	:   2020-07-16
        * @project	:  FlyWeight
    *************************************/
    #include <iostream>
    #include <random>
    #include <time.h>
    #include <thread>
    #include <unistd.h>
    #include "checkerboard.h"
    #include "piecefactory.h"
    #include "piece.h"
    
    using namespace std;
    
    void GeneratePoint(Piece* p)
    {//随机数生成有点问题
        std::mt19937 rnd(time(0));
        p->m_X = rnd()%20;
        p->m_Y = rnd()%20;
    }
    
    int main()
    {
        CheckerBoard board;
        board.Draw();
    
        PieceFactory factory;
        for(int n = 0; n < 20; ++n)
        {
            Piece* p1 = factory.find(Color::black);
            GeneratePoint(p1);
    
            sleep(1);
    
            Piece* p2 = factory.find(Color::white);
            GeneratePoint(p2);
    
            board.GetPiece(*p2);
            board.GetPiece(*p1);
            board.refresh();
        }
    
        return 0;
    }
    
    
    • 运行结果

    oooooooooooooooooooo

    oooooooooo+ooooooooo

    -+oooooooooooooooooo

    oooooooooooooooooooo

    ooooooo-oooo+oo+oooo

    oooooooooooooooooooo

    o+oooooooooooooooooo

    oooo++oo+ooooooooooo

    注:随机数生成算法有点问题,这里忽略最终结果

    优点

    模式的优点

    • 享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本都是相同的,有时就能够受大幅度地减少需要实例化的类的数量。如果能把哪些参数移到类实例的外面,在方法调用的时候将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。

    缺点

    模式的缺点

    • 使用享元模式需要维护一个记录了系统已有的所有享元的列表,而这本身需要耗费资源。
    • 享元模式使得系统更加的复杂,为了使对象可以共享,需要将一些状态外部化,这是得程序的逻辑复杂化。因此,应当在有足够多的对象实例可供共享时才值得使用享元模式。
  • 相关阅读:
    理解CSS定位中的overflow和visibility属性
    理解CSS定位中的position
    理解margin负值,实现经典布局
    理解CSS定位中的float
    CSS表格属性
    图解一步步安装SharePoint Foundation 2010
    Gladinet Cloud Desktop Professional License(专业版序列号)
    配置SharePoint Foundation 2010基于表单的验证支持
    快逸报表部署心得
    如何阅读公司财务报告
  • 原文地址:https://www.cnblogs.com/wzxNote/p/13330211.html
Copyright © 2011-2022 走看看