首页 > 编程语言 >c/c++设计模式---享元模式

c/c++设计模式---享元模式

时间:2024-06-03 11:10:32浏览次数:31  
标签:享元 设计模式 对象 --- nmsp2 nmsp1 Position Piece

引入享元模式:

围棋游戏:

namespace _nmsp1
{
    enum EnumColor //棋子类型
    {
        Black, //黑
        White  //白
    };
    struct Position //棋子位置
    {
        int m_x;
        int m_y;
        Position(int tmpx, int tmpy) :m_x(tmpx), m_y(tmpy) {} //构造函数            
    };
    class Piece //棋子
    {
    public:
        Piece(EnumColor tmpcolor, Position tmppos) :m_color(tmpcolor), m_pos(tmppos) {} //构造函数

        void draw() //棋子的绘制
        {
            if (m_color == Black)
            {
                cout << "在位置:(" << m_pos.m_x << "," <<  m_pos.m_y << ")处绘制了一个黑色棋子!" << endl;
                //....这里可以是一系列用于具体绘制的代码
            }
            else
            {
                cout << "在位置:(" << m_pos.m_x <<  "," << m_pos.m_y << ")处绘制了一个白色棋子!" << endl;
                //....这里可以是一系列用于具体绘制的代码
            }
        }
    private:
        EnumColor m_color; //棋子颜色
        Position m_pos; //棋子位置
    };

    
}
int main()
{

std::list<_nmsp1::Piece*> piecelist; 

    _nmsp1::Piece* p_piece1 = new _nmsp1::Piece(_nmsp1::Black, _nmsp1::Position(3, 3)); //黑色落子到3,3位置
    p_piece1->draw();

    _nmsp1::Piece* p_piece2 = new _nmsp1::Piece(_nmsp1::White, _nmsp1::Position(5, 5)); //白色落子到5,5位置
    p_piece2->draw();

    _nmsp1::Piece* p_piece3 = new _nmsp1::Piece(_nmsp1::Black, _nmsp1::Position(4, 6)); //黑色落子到4,6位置
    p_piece3->draw();

    _nmsp1::Piece* p_piece4 = new _nmsp1::Piece(_nmsp1::White, _nmsp1::Position(5, 7)); //白色落子到5,7位置
    p_piece4->draw();
    //.....


    piecelist.push_back(p_piece1);
    piecelist.push_back(p_piece2);
    piecelist.push_back(p_piece3);
    piecelist.push_back(p_piece4);


    //释放资源
    delete p_piece1;
    delete p_piece2;
    delete p_piece3;
    delete p_piece4;


}

 

享元模式实现:

 

namespace _nmsp2
{
    enum EnumColor //棋子类型
    {
        Black, //黑
        White  //白
    };
    struct Position //棋子位置
    {
        int m_x;
        int m_y;
        Position(int tmpx, int tmpy) :m_x(tmpx), m_y(tmpy) {} //构造函数            
    };

    class Piece //棋子抽象类
    {
    public:
        virtual ~Piece() {} //做父类时析构函数应该为虚函数
    public:
        virtual void draw(Position tmppos) = 0;
    };

    class BlackPiece :public Piece //黑色棋子
    {
    public:
        //int ins;
        virtual void draw(Position tmppos)
        {
            cout << "在位置:(" << tmppos.m_x << "," << tmppos.m_y << ")处绘制了一个黑色棋子!" << endl;
            //....这里可以是一系列用于具体绘制的代码
        }
    };

    class WhitePiece :public Piece //白色棋子
    {
    public:
        virtual void draw(Position tmppos)
        {
            cout << "在位置:(" << tmppos.m_x << "," << tmppos.m_y << ")处绘制了一个白色棋子!" << endl;
            //....这里可以是一系列用于具体绘制的代码
        }
    };

    class pieceFactory //创建棋子的工厂
    {
    public:
        virtual ~pieceFactory() 
        {
            //释放内存
            for (auto iter = m_FlyWeightMap.begin(); iter != m_FlyWeightMap.end(); ++iter)
            {
                Piece* tmpfw = iter->second;
                delete tmpfw;
            }
            m_FlyWeightMap.clear(); //可有可无
        }

        Piece* getFlyWeight(EnumColor tmpcolor) //获取享元对象,也就是获取被共享的棋子对象
        {
            auto iter = m_FlyWeightMap.find(tmpcolor);
            if (iter == m_FlyWeightMap.end())
            {
                //没有该享元对象,那么就创建出来
                Piece* tmpfw = nullptr;
                if (tmpcolor == Black) //黑子
                {
                    tmpfw = new BlackPiece();
                }
                else //白子
                {
                    tmpfw = new WhitePiece();
                }
                m_FlyWeightMap.insert(make_pair(tmpcolor, tmpfw)); //以棋子颜色枚举值作为key,增加条目到map中
                return tmpfw;
            }
            else
            {
                return iter->second;
            }
        }

    private:
        std::map<EnumColor, Piece*> m_FlyWeightMap; //享元池,用map容器来保存所有的享元对象,一共就两个享元对象(黑色棋子一个,白色棋子一个)
    };

}

int main()
{

_nmsp2::pieceFactory* pfactory = new _nmsp2::pieceFactory();

    _nmsp2::Piece* p_piece1 = pfactory->getFlyWeight(_nmsp2::Black);
    p_piece1->draw(_nmsp2::Position(3, 3));  //黑子落子到3,3位置

    _nmsp2::Piece* p_piece2 = pfactory->getFlyWeight(_nmsp2::White);
    p_piece2->draw(_nmsp2::Position(5, 5));  //白子落子到5,5位置

    _nmsp2::Piece* p_piece3 = pfactory->getFlyWeight(_nmsp2::Black);
    p_piece3->draw(_nmsp2::Position(4, 6));  //黑子落子到4,6位置

    _nmsp2::Piece* p_piece4 = pfactory->getFlyWeight(_nmsp2::White);
    p_piece4->draw(_nmsp2::Position(5, 7));  //白子落子到5,7位置


    //释放资源
    delete  pfactory;
    
    return 0;

}

     享元(Flyweight)模式:蝇量模式,结构型模式,解决的是面向对象程序设计的性能问题     //享元:被共享的单元或者被共享的对象。Flyweight——轻量级(占用的内存更少)。     //设计思想:当需要某个对象时,尽量共用已经创建出的同类对象从而避免频繁使用new创建同类或者相似的对象。     //(1)从一个典型的范例开始     //享元对象(被共享的对象):黑棋,白棋     //(2)引入享元(Flyweight)模式     //该模式避免了程序中出现大量相同或者相似的对象,通过共享对象的方式实现相似对象的重用。     //定义:运用共享技术有效地支持大量细粒度的对象(的复用)。
    //内部状态:存储在享元对象内部,一直不会发生改变的状态。这种状态可以被共享。     //外部状态:随着外部环境和各种动作因素的改变而发生改变的状态,这种状态不可以被共享。     //     //享元模式的目的:减少对象数量,节省内存,提高程序运行效率。
    //三种角色:     //a)Flyweight(抽象享元类):Piece类     //b)ConcreteFlyweight(具体享元类):BlackPiece、WhitePiece。     //c)FlyWeightFactory(享元工厂类):pieceFactory
    //使用情形:     //a)程序中有大量相同或者相似对象造成内存大量消耗。     //b)对象的大部分状态都是或者都可以转变成外部状态,通过参数传入到对象中。     //c)享元池的引入增加了程序实现的复杂性,当然也有一定内存开销,使用享元模式要衡量性价比。
    //不要将享元模式  对象池,连接池,线程池等混为一谈。

享元模式是一种结构型设计模式,旨在减少应用程序中相似对象的内存使用或计算成本,通过共享相同状态的对象实例来达到节省资源的目的。在享元模式中,共享的对象被称为“享元”,而对于不同的上下文或情境,可以通过在享元对象中维护外部状态来实现个性化。

这个模式的关键思想是将对象的状态分为内部状态和外部状态。内部状态是对象共享的部分,存储在享元对象内部;而外部状态是对象可变的部分,需要在运行时由客户端传递给享元对象。通过这种方式,可以在不同的上下文中重用相同的享元对象,从而节省内存和提高性能。

享元模式通常与工厂模式结合使用,以便动态创建和管理享元对象。这种模式在需要大量相似对象时特别有用,例如图形编辑器中的图形对象,游戏中的粒子效果,或者操作系统中的字体对象。

 

下面是一个简单的 C++ 代码示例,演示了如何使用享元模式来共享相同状态的对象实例:

#include <iostream>
#include <unordered_map>

// 享元对象类
class Flyweight {
public:
    virtual void operation(int extrinsicState) = 0;
};

// 具体享元对象类
class ConcreteFlyweight : public Flyweight {
public:
    void operation(int extrinsicState) override {
        std::cout << "具体享元对象操作,外部状态:" << extrinsicState << std::endl;
    }
};

// 享元工厂类
class FlyweightFactory {
private:
    std::unordered_map<std::string, Flyweight*> flyweights;

public:
    Flyweight* getFlyweight(std::string key) {
        if (flyweights.find(key) == flyweights.end()) {
            flyweights[key] = new ConcreteFlyweight();
        }
        return flyweights[key];
    }
};

int main() {
    FlyweightFactory factory;
    
    Flyweight* fw1 = factory.getFlyweight("key1");
    fw1->operation(1);
    
    Flyweight* fw2 = factory.getFlyweight("key2");
    fw2->operation(2);
    
    Flyweight* fw3 = factory.getFlyweight("key1");
    fw3->operation(3); // 复用了fw1对应的享元对象
    
    return 0;
}

在这个例子中,ConcreteFlyweight 是具体的享元对象类,实现了 Flyweight 接口。FlyweightFactory 是享元工厂类,负责创建和管理享元对象。在 main 函数中,演示了如何通过享元工厂获取共享的享元对象,并传递外部状态进行操作。由于重复使用了相同的 key,可以看到第一个和第三个操作使用了同一个享元对象。

这里只是一个简单的示例,实际应用中可能会更复杂,需要根据具体情况来设计和实现享元模式。

 

标签:享元,设计模式,对象,---,nmsp2,nmsp1,Position,Piece
From: https://www.cnblogs.com/bwbfight/p/18228403

相关文章

  • FIREYE 45UV5-1101 紫外线火焰探测器
    FIREYE45UV5-1101紫外线火焰探测器的详细介绍如下:基本信息:品牌:FIREYE型号:45UV5-1101类型:紫外线火焰探测器技术特点:检测原理:采用紫外线技术,能够检测火焰中的紫外线辐射,光学范围通常在190至250纳米之间。灵敏度与可靠性:高度的灵敏度和可靠性,能够在各种恶劣环境下稳定......
  • 关于网易游戏官网-部分游戏页面特效实现思路的简述
    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)https://www.cnblogs.com/cnb-yuchen/p/18032062>出自【进步*于辰的博客】大学学习前端的时候,我们团队以【网易游戏官网】中的部分游戏页面作为参考开发了一些页面作为实训作品(作品源码我已上传→网易游戏官网-部......
  • Oracle系列---【ORA-00257: Archiver error. Connect AS SYSDBA only until resolved
    ORA-00257:Archivererror.ConnectASSYSDBAonlyuntilresolved1.问题描述过了个周末,发现系统登录不上了,查看日志,发现报"ORA-00257:Archivererror.ConnectASSYSDBAonlyuntilresolved",明显数据库有问题了,我用客户端连,也报这个错误。2.问题分析经过一番查询,是因......
  • Linux -- 环境变量与文件查找
    提示:制作不易看完点个关注和收藏哦前言提示:要解释环境变量,得先明白变量是什么,准确的说应该是Shell变量,所谓变量就是计算机中用于记录一个值(不一定是数值,也可以是字符或字符串)的符号,而这些符号将用于不同的运算处理中。通常变量与值是一对一的关系,可以通过表达式读取它的......
  • Honeywell CC-PFB401 控制器 电源模块系统备件
    HoneywellCC-PFB401控制器电源模块系统备件是一款专为工业自动化系统设计的备品备件。以下是关于该备件的详细信息和特点:基本信息品牌:Honeywell型号:CC-PFB401类型:控制器电源模块系统备件技术规格工作电压:24VDC输出频率:30Hz处理速度:15Hz程序容量:3MB数据容量:1MB认证......
  • QNX-9—QNX官网文档翻译—中断-3—Writing an Interrupt Handler
    翻译:QNXSoftwareDevelopmentPlatform-->Programming-->Programmer'sGuidehttps://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.prog/topic/inthandler.html前言:及时处理硬件事件的关键是硬件产生中断。中断只是处理器正在执行的操作的暂停或中断......
  • # 数据转换-16进制字符
    数据转换-16进制字符任务详情在openEuler(推荐)或Ubuntu或Windows(不推荐)中完成下面任务,使用git管理代码,gitcommit不能少于5次在附件中的utils.h和utils.c中完成16进制字符'0'-'9','A'-'F','a'-'f'与十六进制数据0-15的转换功能(10’):intHex2Char(unsignedintfromi......
  • 数据转换-整数字节数组
    数据转换-整数字节数组一、任务详情在openEuler(推荐)或Ubuntu或Windows(不推荐)中完成下面任务,使用git管理代码,gitcommit不能少于5次1参考《GMT0009-2012SM2密码算法使用规范》第6节“数据转换”在utils.h和utils.c中完成整数与8位字节串的转换功能(10'):intInt2ByteArr......
  • 【2024-06-01】连岳摘抄
    23:59向着明亮那方,向着明亮那方。哪怕一片叶子,也要向着日光洒下的方向。灌木丛中的小草啊。向着明亮那方,向着明亮那方。哪怕烧焦了翅膀,也要飞向灯火闪烁的方向。夜里的飞虫啊。向着明亮那方,向着明亮那方。哪怕只是分寸的宽敞,也要向着阳光照射的方向。住在城市的孩子们啊!住在乡......
  • 疯狂的麦克斯:狂暴女神迅雷下载/HD1.82高清版下载-百度云资源
    近年来,影视作品中出现了许多以废土世界为背景的电影,其中最为引人注目的便是乔治·米勒执导的《疯狂的麦克斯:狂暴女神》。该片以狂野、快节奏和暴力场面著称,讲述了一个在无法无天的沙漠中生存的主角麦克斯与一群勇敢的女性战士们的故事。然而,与其他废土题材电影不同的是,《疯狂......