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

设计模式每日硬核训练 Day 15:享元模式(Flyweight Pattern)完整讲解与实战应用

🔄 回顾 Day 14:组合模式小结

在 Day 14 中,我们学习了组合模式(Composite Pattern):

  • 适用于构建树状层级结构,使得“单个对象”和“对象集合”统一操作。
  • 广泛用于文件系统、UI 控件树、组织结构等。

而今天的主角“享元模式”,是极致优化资源的代表。

享元模式(Flyweight Pattern)用于共享对象,减少内存占用,提升系统性能。


一、享元模式的核心动机

在系统中,如果存在大量“内容相同或相似”的对象,重复创建将造成资源浪费。

✅ 比如:

  • 文本编辑器中成千上万个字符对象
  • 游戏中上千棵树、子弹、砖块、粒子
  • 地图系统中多个城市的图标

如果这些对象的“大部分状态相同”,我们就可以将它们共享起来,避免重复创建
在这里插入图片描述


二、结构图(UML)

+----------------+      +--------------------+
|  Flyweight     |<-----|  ConcreteFlyweight |
+----------------+      +--------------------+
| +operation()   |      | - intrinsicState   |
+----------------+      | +operation()       |+--------------------++----------------+         +-----------------------+
| FlyweightFactory |------>| Flyweight Pool        |
+----------------+         +-----------------------+
| +getFlyweight() |

三、术语说明:

概念含义描述
Intrinsic State内部状态(可共享、不变)
Extrinsic State外部状态(不共享,由客户端提供)
Flyweight享元接口,定义共享对象应有操作
ConcreteFlyweight实现享元的具体对象
FlyweightFactory管理共享对象池(享元工厂)

四、C++ 实现:字符渲染引擎

我们模拟一个文本渲染系统,文字中的每个字符都是一个对象,但字符本身可共享,坐标位置不可共享。

✅ Flyweight 接口

class Glyph {
public:virtual void render(int x, int y) = 0; // Extrinsicvirtual ~Glyph() = default;
};

✅ 共享对象:ConcreteFlyweight

class CharacterGlyph : public Glyph {char symbol_; // Intrinsic State
public:CharacterGlyph(char ch) : symbol_(ch) {}void render(int x, int y) override {std::cout << "绘制字符 '" << symbol_ << "' at (" << x << "," << y << ")\n";}
};

✅ 享元工厂

class GlyphFactory {std::unordered_map<char, std::shared_ptr<Glyph>> pool_;public:std::shared_ptr<Glyph> getGlyph(char ch) {if (!pool_.count(ch)) {pool_[ch] = std::make_shared<CharacterGlyph>(ch);}return pool_[ch];}
};

✅ 使用示例

int main() {GlyphFactory factory;std::string text = "AABAC";int x = 0;for (char ch : text) {auto glyph = factory.getGlyph(ch); // 共享对象glyph->render(x, 0);               // 外部状态:坐标x += 10;}return 0;
}

输出:

绘制字符 'A' at (0,0)
绘制字符 'A' at (10,0)
绘制字符 'B' at (20,0)
绘制字符 'A' at (30,0)
绘制字符 'C' at (40,0)

五、实战应用场景

场景享元内容说明
文本编辑器字符对象:字体、颜色共享,位置不共享
游戏地图渲染大量树木、草丛、砖块共享对象,坐标单独记录
数据可视化系统图标、图例、样式重复,减少渲染对象数量
图标资源池图标素材在多个地方复用,统一缓存
数据库连接池多个线程共用固定连接对象,提升资源复用率

六、优缺点分析

✅ 优点:

  • 极大节省内存资源(大量对象时提升明显)
  • 避免重复对象创建,提升性能
  • 中央控制共享对象更可控

❗ 缺点:

  • 管理复杂,需划分共享状态/外部状态
  • 外部状态维护变复杂,需由使用者负责传入

七、与单例/对象池/享元的区别

模式共享粒度对象数量控制核心目的
单例全局单一只能有 1 个全局唯一对象
对象池共享对象集合固定数量(动态管理)控制创建/复用的生命周期
享元每类一个共享对象可复用对象很多减少对象创建,提高复用率

八、面试表达模板

“我们在文本渲染模块中使用了享元模式来复用字符对象,字符本身作为内部状态共享,坐标作为外部状态传入。通过 GlyphFactory 管理共享对象池,节省了内存占用并提升渲染性能,特别适合大量字符的 UI 场景。”

✅ 建议强调共享 vs 非共享状态划分、工厂管理、资源优化作用。


九、口诀记忆

“不变共用做享元,状态分离省内存;池中拿来直接用,场景重复效率增。”


十、明日预告:Day 16

责任链模式(Chain of Responsibility Pattern):请求沿链传递,节点动态决定处理权,构建灵活的处理流程结构。

http://www.xdnf.cn/news/6535.html

相关文章:

  • MCP协议在纳米材料领域的深度应用:从跨尺度协同到智能研发范式重构
  • spring响应式编程系列:总体流程
  • Ubuntu18.04安装Qt5.12
  • 在PyCharm中部署AI模型的完整指南
  • 鸿蒙-跨设备互通,设备互通提供跨设备的相机、扫描、图库访问能力,平板或2in1设备可以调用手机的相机、扫描、图库等功能。
  • 【VSCode】在 VSCode 中运行 HTML 页面并通过 HTTPS 访问
  • 在pycharm中搭建yolo11分类检测系统--PyQt5学习(二)
  • 发现“横”字手写有难度,对比两个“横”字
  • CSS3笔记
  • 小知识合集 慢慢更新
  • vue,uniapp解决h5跨域问题
  • uniapp打包IOS私钥证书过期了,如何在非mac系统操作
  • PDK中technology file从tf格式转换为lef格式
  • 【AI插件开发】Notepad++ AI插件开发实践:支持配置界面
  • 双轮驱动能源革命:能源互联网与分布式能源赋能工厂能效跃迁
  • 在Ubuntu系统中安装和升级RabbitVCS
  • 【教程】无视硬件限制强制升级Windows 11
  • 《数据结构之美--链表oj练习》
  • 2026《数据结构》考研复习笔记三(C++高级教程)
  • 「数据可视化 D3系列」入门第十章:饼图绘制详解与实现
  • 《实战AI智能体》——邮件转工单的AI自动化
  • 「数据可视化 D3系列」入门第十一章:力导向图深度解析与实现
  • 设计模式 --- 装饰器模式
  • 通过 Zotero 的样式编辑器(Style Editor)自定义文献引用和参考文献列表的格式
  • 在阿里云虚拟主机上启用WordPress伪静态
  • Redis 的指令执行方式:Pipeline、事务与 Lua 脚本的对比
  • HTTP:九.WEB机器人
  • 探索 HumanoidBench:类人机器人学习的新平台
  • 甘果桌面tv版下载-甘果桌面安卓电视版使用教程
  • OpenAI 34页最佳构建Agent实践