Răsfoiți Sursa

V0.9.7
1、添加了享元模式

Apple 6 zile în urmă
părinte
comite
86965b9a21

+ 2 - 0
demo/DesignerPattern/CMakeLists.txt

@@ -14,6 +14,8 @@ file(GLOB LOCAL_SRC
     ${CMAKE_CURRENT_SOURCE_DIR}/AbstractFactory/*.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/Builder/*.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/Iterator/*.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/FlyWeight/*.cpp
+
 )
 
 

+ 49 - 0
demo/DesignerPattern/FlyWeight/FlyWeifht.cpp

@@ -0,0 +1,49 @@
+#include "FlyWeifht.h"
+#include <list>
+#include <spdlog.h>
+#include <vector>
+
+
+
+void testFlyWeight()
+{
+    /* 创建炸弹工厂 */
+    BombFactory bombFactory;
+    /* 需要的炸弹列表 */
+    std::vector<std::tuple<std::string, std::string, int, int, int>> bombList = {
+        {"普通炸弹", "红色", 10, 20, 5},
+        {"普通炸弹", "红色", 15, 25, 5},
+        {"普通炸弹", "蓝色", 20, 30, 7},
+        {"普通炸弹", "蓝色", 25, 35, 7},
+        {"普通炸弹", "红色", 30, 40, 5},
+        {"唯一炸弹", "金色", 50, 60, 10}
+    };
+    std::list<LaunchBomb*> launchedBombs;
+    for(auto it : bombList)
+    {
+        std::string type = std::get<0>(it);
+        std::string color = std::get<1>(it);
+        int x = std::get<2>(it);
+        int y = std::get<3>(it);
+        int speed = std::get<4>(it);
+
+        if (type == "唯一炸弹")
+        {
+            UniqueBomb* pUniqueBomb = new UniqueBomb(type, color);
+            pUniqueBomb->move(x, y, speed);
+            LaunchBomb* bomb = new LaunchBomb(pUniqueBomb);
+            bomb->move(x, y);
+            launchedBombs.push_back(bomb);
+            SPDLOG_INFO("-----------------------------");
+        }
+        else
+        {
+            ShareBombBody* pShareBombBody = bombFactory.getShareBombBody(type, color);
+            pShareBombBody->move(x, y, speed);
+            LaunchBomb* bomb = new LaunchBomb(pShareBombBody);
+            bomb->move(x, y);
+            launchedBombs.push_back(bomb);
+            SPDLOG_INFO("-----------------------------");
+        }
+    }
+}

+ 172 - 0
demo/DesignerPattern/FlyWeight/FlyWeifht.h

@@ -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__

+ 4 - 1
demo/DesignerPattern/main.cpp

@@ -9,6 +9,7 @@
 #include "Prototype/Prototype.h"
 #include "Adapter/Adapter.h"
 #include "Iterator/IteratorDemo.h"
+#include "FlyWeight/FlyWeifht.h"
 
 
 int main(int argc, char *argv[])
@@ -48,7 +49,9 @@ int main(int argc, char *argv[])
     // delete translator;
     // delete french;
 
-    testRingQueueManualMutex();
+    // testRingQueueManualMutex();
+
+    testFlyWeight();
 
 
     return a.exec();