#ifndef __FLYWEIGHT_H__ #define __FLYWEIGHT_H__ /** 享元模式 享元模式是一种结构型设计模式,旨在通过共享对象来减少内存使用和提高性能。 它适用于大量相似对象的场景,通过将对象的状态分为内部状态(可以共享)和外部状态(不可共享),从而实现对象的复用。 主要角色: 1. Flyweight(享元接口):定义了享元对象的公共接口。 2. ConcreteFlyweight(具体享元类):实现了享元接口,并存储了内部状态。 3. FlyweightFactory(享元工厂):负责创建和管理享元对象,确保共享对象的唯一性。 4. Client(客户端):使用享元对象,并传递外部状态。 实例: 这里使用绘制炮弹轨迹的例子来说明享元模式。 */ #include #include #include "spdlog/spdlog.h" /** * @brief 享元基类 * */ class FlyWeightBase { public: FlyWeightBase(const std::string& type, const std::string& color) : m_Type(type), m_Color(color) {} virtual ~FlyWeightBase() {} virtual void move(int x, int y, int speed) = 0; virtual void draw(int x, int y) = 0; protected: std::string m_Type; // 享元类型 std::string m_Color; // 享元颜色 }; /** * 共享数据类,炮弹弹体 * */ class ShareBombBody : public FlyWeightBase { public: using FlyWeightBase::FlyWeightBase; // 继承基类的构造函数 ~ShareBombBody() override {} void move(int x, int y, int speed) override { SPDLOG_INFO("炮弹类型:{},颜色:{},位置:({}, {}), 速度:{}", m_Type, m_Color, x, y, speed); } void draw(int x, int y) override { SPDLOG_INFO("在位置:({}, {}) 重新绘制炸弹弹体", m_Type, m_Color, x, y); } }; /* 一种唯一的彩色炸弹 */ class UniqueBomb : public FlyWeightBase { public: using FlyWeightBase::FlyWeightBase; // 继承基类的构造函数 ~UniqueBomb() override {} void move(int x, int y, int speed) override { SPDLOG_INFO("唯一炸弹类型:{},颜色:{},位置:({}, {}), 速度:{}", m_Type, m_Color, x, y, speed); } void draw(int x, int y) override { SPDLOG_INFO("在位置:({}, {}) 重新绘制唯一炸弹", m_Type, m_Color, x, y); } }; /* 发射炮弹 */ class LaunchBomb { public: LaunchBomb(FlyWeightBase* pShareBombBody) : m_pFlyWeight(pShareBombBody), m_X(0), m_Y(0), m_Speed(100) {} int getX() const { return m_X; } int getY() const { return m_Y; } int getSpeed() const { return m_Speed; } void setX(int x) { m_X = x; } void setY(int y) { m_Y = y; } void setSpeed(int speed) { m_Speed = speed; } void move(int x, int y) { m_X = x; m_Y = y; m_pFlyWeight->move(m_X, m_Y, m_Speed); draw(); } void draw() { m_pFlyWeight->draw(m_X, m_Y); } private: FlyWeightBase* m_pFlyWeight; // 共享的炮弹弹体 int m_X; // 炮弹位置X int m_Y; // 炮弹位置Y int m_Speed; // 炮弹速度 }; /* 炸弹工厂类(享元工厂) */ class BombFactory { public: ~BombFactory() { // 释放享元对象池中的所有对象 for (auto& pair : m_mapBomb) { delete pair.second; } m_mapBomb.clear(); } ShareBombBody* getShareBombBody(const std::string& type, const std::string& color) { std::string key = type + "_" + color; auto it = m_mapBomb.find(key); if (it != m_mapBomb.end()) { SPDLOG_INFO("从享元池中获取已有的炮弹弹体: {}", key); return it->second; } else { SPDLOG_INFO("创建新的炮弹弹体: {}", key); ShareBombBody* pNewBomb = new ShareBombBody(type, color); m_mapBomb[key] = pNewBomb; return pNewBomb; } } private: std::map m_mapBomb; // 享元对象池 }; void testFlyWeight(); #endif // __FLYWEIGHT_H__