FlyWeifht.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #ifndef __FLYWEIGHT_H__
  2. #define __FLYWEIGHT_H__
  3. /**
  4. 享元模式
  5. 享元模式是一种结构型设计模式,旨在通过共享对象来减少内存使用和提高性能。
  6. 它适用于大量相似对象的场景,通过将对象的状态分为内部状态(可以共享)和外部状态(不可共享),从而实现对象的复用。
  7. 主要角色:
  8. 1. Flyweight(享元接口):定义了享元对象的公共接口。
  9. 2. ConcreteFlyweight(具体享元类):实现了享元接口,并存储了内部状态。
  10. 3. FlyweightFactory(享元工厂):负责创建和管理享元对象,确保共享对象的唯一性。
  11. 4. Client(客户端):使用享元对象,并传递外部状态。
  12. 实例:
  13. 这里使用绘制炮弹轨迹的例子来说明享元模式。
  14. */
  15. #include <map>
  16. #include <string>
  17. #include "spdlog/spdlog.h"
  18. /**
  19. * @brief 享元基类
  20. *
  21. */
  22. class FlyWeightBase
  23. {
  24. public:
  25. FlyWeightBase(const std::string& type, const std::string& color)
  26. : m_Type(type), m_Color(color) {}
  27. virtual ~FlyWeightBase() {}
  28. virtual void move(int x, int y, int speed) = 0;
  29. virtual void draw(int x, int y) = 0;
  30. protected:
  31. std::string m_Type; // 享元类型
  32. std::string m_Color; // 享元颜色
  33. };
  34. /**
  35. * 共享数据类,炮弹弹体
  36. *
  37. */
  38. class ShareBombBody : public FlyWeightBase
  39. {
  40. public:
  41. using FlyWeightBase::FlyWeightBase; // 继承基类的构造函数
  42. ~ShareBombBody() override {}
  43. void move(int x, int y, int speed) override
  44. {
  45. SPDLOG_INFO("炮弹类型:{},颜色:{},位置:({}, {}), 速度:{}",
  46. m_Type, m_Color, x, y, speed);
  47. }
  48. void draw(int x, int y) override
  49. {
  50. SPDLOG_INFO("在位置:({}, {}) 重新绘制炸弹弹体",
  51. m_Type, m_Color, x, y);
  52. }
  53. };
  54. /* 一种唯一的彩色炸弹 */
  55. class UniqueBomb : public FlyWeightBase
  56. {
  57. public:
  58. using FlyWeightBase::FlyWeightBase; // 继承基类的构造函数
  59. ~UniqueBomb() override {}
  60. void move(int x, int y, int speed) override
  61. {
  62. SPDLOG_INFO("唯一炸弹类型:{},颜色:{},位置:({}, {}), 速度:{}",
  63. m_Type, m_Color, x, y, speed);
  64. }
  65. void draw(int x, int y) override
  66. {
  67. SPDLOG_INFO("在位置:({}, {}) 重新绘制唯一炸弹",
  68. m_Type, m_Color, x, y);
  69. }
  70. };
  71. /* 发射炮弹 */
  72. class LaunchBomb
  73. {
  74. public:
  75. LaunchBomb(FlyWeightBase* pShareBombBody)
  76. : m_pFlyWeight(pShareBombBody), m_X(0), m_Y(0), m_Speed(100) {}
  77. int getX() const { return m_X; }
  78. int getY() const { return m_Y; }
  79. int getSpeed() const { return m_Speed; }
  80. void setX(int x) { m_X = x; }
  81. void setY(int y) { m_Y = y; }
  82. void setSpeed(int speed) { m_Speed = speed; }
  83. void move(int x, int y)
  84. {
  85. m_X = x;
  86. m_Y = y;
  87. m_pFlyWeight->move(m_X, m_Y, m_Speed);
  88. draw();
  89. }
  90. void draw()
  91. {
  92. m_pFlyWeight->draw(m_X, m_Y);
  93. }
  94. private:
  95. FlyWeightBase* m_pFlyWeight; // 共享的炮弹弹体
  96. int m_X; // 炮弹位置X
  97. int m_Y; // 炮弹位置Y
  98. int m_Speed; // 炮弹速度
  99. };
  100. /* 炸弹工厂类(享元工厂) */
  101. class BombFactory
  102. {
  103. public:
  104. ~BombFactory()
  105. {
  106. // 释放享元对象池中的所有对象
  107. for (auto& pair : m_mapBomb)
  108. {
  109. delete pair.second;
  110. }
  111. m_mapBomb.clear();
  112. }
  113. ShareBombBody* getShareBombBody(const std::string& type, const std::string& color)
  114. {
  115. std::string key = type + "_" + color;
  116. auto it = m_mapBomb.find(key);
  117. if (it != m_mapBomb.end())
  118. {
  119. SPDLOG_INFO("从享元池中获取已有的炮弹弹体: {}", key);
  120. return it->second;
  121. }
  122. else
  123. {
  124. SPDLOG_INFO("创建新的炮弹弹体: {}", key);
  125. ShareBombBody* pNewBomb = new ShareBombBody(type, color);
  126. m_mapBomb[key] = pNewBomb;
  127. return pNewBomb;
  128. }
  129. }
  130. private:
  131. std::map<std::string, ShareBombBody*> m_mapBomb; // 享元对象池
  132. };
  133. void testFlyWeight();
  134. #endif // __FLYWEIGHT_H__