|
@@ -0,0 +1,172 @@
|
|
|
|
+#ifndef __FLYWEIGHT_H__
|
|
|
|
+#define __FLYWEIGHT_H__
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ 享元模式
|
|
|
|
+ 享元模式是一种结构型设计模式,旨在通过共享对象来减少内存使用和提高性能。
|
|
|
|
+ 它适用于大量相似对象的场景,通过将对象的状态分为内部状态(可以共享)和外部状态(不可共享),从而实现对象的复用。
|
|
|
|
+
|
|
|
|
+ 主要角色:
|
|
|
|
+ 1. Flyweight(享元接口):定义了享元对象的公共接口。
|
|
|
|
+ 2. ConcreteFlyweight(具体享元类):实现了享元接口,并存储了内部状态。
|
|
|
|
+ 3. FlyweightFactory(享元工厂):负责创建和管理享元对象,确保共享对象的唯一性。
|
|
|
|
+ 4. Client(客户端):使用享元对象,并传递外部状态。
|
|
|
|
+
|
|
|
|
+ 实例:
|
|
|
|
+ 这里使用绘制炮弹轨迹的例子来说明享元模式。
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#include <map>
|
|
|
|
+#include <string>
|
|
|
|
+
|
|
|
|
+#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<std::string, ShareBombBody*> m_mapBomb; // 享元对象池
|
|
|
|
+
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+void testFlyWeight();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+#endif // __FLYWEIGHT_H__
|