当前位置: 首页 > article >正文

C++ 设计模式:享元模式(Flyweight Pattern)

链接:C++ 设计模式
链接:C++ 设计模式 - 单例模式

享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享尽可能多的相同对象来减少内存使用和提高性能。享元模式适用于大量细粒度对象的场景,这些对象之间有很多相同的部分,可以通过共享来减少内存消耗。

1.问题分析

在开发中,尤其是在需要大量细粒度对象的场景中,内存使用和性能优化是两个重要的考虑因素。例如,在图形界面、文本编辑器、游戏开发等领域,可能会有大量相似或相同的对象需要频繁创建和使用。如果每次都创建新的对象,不仅会占用大量内存,还会导致性能下降。

为了解决这些问题,我们可以结合工厂方法模式和延迟初始化来实现享元模式。具体来说,我们可以定义一个工厂类,通过延迟初始化和独立工厂函数来动态创建和缓存具体的对象。

2.实现步骤:

  1. 定义享元接口:定义一个抽象的接口,包含一个执行方法。
  2. 实现具体享元类:实现享元接口,定义具体的类。
  3. 定义独立工厂函数:定义一个独立的工厂函数,用于根据类型动态创建具体的对象。
  4. 实现享元工厂:实现一个工厂类,通过延迟初始化和独立工厂函数来动态创建和缓存具体的对象。
  5. 客户端代码:使用享元工厂获取具体对象,并执行。

3.代码示例

以机器人舞蹈动作作为示例。

3.1.定义享元接口

// 享元接口
class DanceMove {
 public:
  virtual ~DanceMove() = default;
  virtual void execute() = 0;
};

3.2.实现具体享元类

// 具体享元类1,抬手动作
class RaiseHand : public DanceMove {
 public:
  void execute() override { std::cout << "Executing Raise Hand Move" << std::endl; }
};
// 具体享元类2,转身动作
class TurnAround : public DanceMove {
 public:
  void execute() override { std::cout << "Executing Turn Around Move" << std::endl; }
};
// 具体享元类3,踢腿动作
class KickLeg : public DanceMove {
 public:
  void execute() override { std::cout << "Executing Kick Leg Move" << std::endl; }
};

3.3.定义独立工厂函数

// 独立工厂函数
std::shared_ptr<DanceMove> createDanceMove(const std::string& type) {
  if (type == "RaiseHand") {
    return std::make_shared<RaiseHand>();
  } else if (type == "TurnAround") {
    return std::make_shared<TurnAround>();
  } else if (type == "KickLeg") {
    return std::make_shared<KickLeg>();
  } else {
    return nullptr;
  }
}

3.4.实现享元工厂类

// 享元工厂
class DanceMoveFactory {
 public:
  // 获取舞蹈动作
  std::shared_ptr<DanceMove> getDanceMove(const std::string& type) {
    auto it = danceMoveMap_.find(type);
    if (it != danceMoveMap_.end()) {
      return it->second;
    } else {
      // 创建动作
      std::shared_ptr<DanceMove> danceMove = createDanceMove(type);
      if (danceMove) {
        danceMoveMap_[type] = danceMove;
        return danceMove;
      } else {
        throw std::runtime_error("Dance move type not recognized: " + type);
      }
    }
  }

 private:
  std::unordered_map<std::string, std::shared_ptr<DanceMove>> danceMoveMap_;
};

3.5.客户端代码

// 客户端代码
int main() {
  DanceMoveFactory factory;

  try {
    // 获取并执行舞蹈动作
    auto raiseHand = factory.getDanceMove("RaiseHand");
    raiseHand->execute();

    auto turnAround = factory.getDanceMove("TurnAround");
    turnAround->execute();

    auto kickLeg = factory.getDanceMove("KickLeg");
    kickLeg->execute();

    // 再次获取舞蹈动作,验证是否共享了相同类型的动作对象
    auto raiseHand2 = factory.getDanceMove("RaiseHand");
    raiseHand2->execute();

    std::cout << "raiseHand address: " << raiseHand.get() << std::endl;
    std::cout << "raiseHand2 address: " << raiseHand2.get() << std::endl;

    // 尝试获取未注册的舞蹈动作
    auto unknownMove = factory.getDanceMove("UnknownMove");
    unknownMove->execute();
  } catch (const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
  }

  return 0;
}

http://www.kler.cn/a/457863.html

相关文章:

  • MyBatis-plus sql拦截器
  • kafka开机自启失败问题处理
  • BP神经网络的反向传播算法
  • 在 macOS 上,你可以使用系统自带的 终端(Terminal) 工具,通过 SSH 协议远程连接服务器
  • JVM实战—9.线上FGC的几种案例
  • 整合版canal ha搭建--基于1.1.4版本
  • c#中using语句
  • 【LLM综述】29种大模型Prompt Engineering技术
  • 【大语言模型】LangChain 核心模块介绍(Memorys)
  • Python Polars快速入门指南:LazyFrames
  • 苹果手机iOS18.2系统苹果手机便签测评
  • Type-C接口的拍摄云台
  • OpenCV-Python实战(13)——图像轮廓
  • 【每日学点鸿蒙知识】Provider、Navigation返回参数、隐私声明问题、Text判断函数、自定义hvigor插件
  • 初入图像处理:水稻剑叶夹角测量
  • 【Hackthebox 中英 Write-Up】通过 POST 请求绕过前端限制:基于 Cookie 的认证与数据提取实操指南
  • AI大模型语音识别转文字
  • 在 CentOS 7 上安装 Node.js 20 并升级 GCC、make 和 glibc
  • 图像处理-Ch7-快速小波变换和小波包
  • redis cluster实验详解
  • 蓝桥杯速成教程{三}(adc,i2c,uart)
  • vulhub-wordpress靶场
  • 区块链安全常见的攻击合约和简单复现,附带详细分析——不安全调用漏洞 (Unsafe Call Vulnerability)【6】
  • 【513. 找树左下角的值 中等】
  • 【Leetcode刷题随笔】977 有序数组的平方
  • google广告 google分析