news 2026/2/6 6:29:55

设计模式[11]——享元模式一分钟彻底说清楚

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
设计模式[11]——享元模式一分钟彻底说清楚

设计模式[11]——享元模式一分钟彻底说清楚

一句话定义

通过共享大量细粒度对象的内在状态(不变部分),大幅减少内存占用,让成千上万个相似对象只占用少量内存。

最狠的比喻(软件人专属)

游戏里渲染一片森林:

  • 有10万棵树
  • 树只有5种模型(松树、橡树、桦树、棕榈、樱花树)
  • 每棵树的位置、大小、旋转角度不同(外在状态)
  • 但模型网格、纹理、材质完全相同(内在状态)

不共享:10万份完整模型 → 内存爆炸
享元模式:只存5份模型,所有树共享 → 内存节省99%!

为什么需要它?(坏味道瞬间爆炸)

不用享元,你会这样写:

structTree{Mesh mesh;// 每个树都完整复制一份网格(几MB)Texture texture;Vector3 position;floatscale;};// 10万棵树 = 几GB内存,寄!
和之前模式彻底分清(10秒表)
项目装饰器(Decorator)组合(Composite)外观(Facade)享元(Flyweight)
核心意图动态叠加行为部分-整体统一接口简化复杂子系统共享内在状态节省内存
关键机制包装链树形递归统一入口工厂 + 共享池
对象数量少量中等(树节点)单个外观大量细粒度对象
典型场景流加密/日志UI树/场景图视频转码/编译器游戏渲染、文字处理、粒子系统
口号“层层叠加”“套娃统一”“一键搞定”“千树一面,共享内在”
真实软件例子:游戏场景树渲染(Unreal/Unity风格)
#include<iostream>#include<memory>#include<unordered_map>#include<vector>#include<string>usingnamespacestd;// 1. 享元接口(内在状态只读)classTreeModel{public:virtual~TreeModel()=default;virtualvoidrender(floatx,floaty,floatscale)const=0;virtualstringtype()const=0;};// 2. 具体享元(内在状态:网格、纹理等昂贵资源)classPineTree:publicTreeModel{public:voidrender(floatx,floaty,floatscale)constoverride{cout<<"[共享模型] 松树 @ ("<<x<<","<<y<<") 缩放:"<<scale<<endl;}stringtype()constoverride{return"Pine";}};classOakTree:publicTreeModel{public:voidrender(floatx,floaty,floatscale)constoverride{cout<<"[共享模型] 橡树 @ ("<<x<<","<<y<<") 缩放:"<<scale<<endl;}stringtype()constoverride{return"Oak";}};// 3. 享元工厂(核心:缓存共享对象)classTreeModelFactory{unordered_map<string,unique_ptr<TreeModel>>models;public:TreeModel*getModel(conststring&type){if(!models.count(type)){cout<<"[工厂] 创建新共享模型: "<<type<<endl;if(type=="Pine")models[type]=make_unique<PineTree>();elseif(type=="Oak")models[type]=make_unique<OakTree>();// 真实项目:这里加载网格、纹理等大资源,只加载一次!}returnmodels[type].get();// 返回共享指针}};// 4. 外在状态(每个树实例独有,轻量)structTreeInstance{floatx,y;floatscale;TreeModel*model;// 指向共享的享元voidrender()const{model->render(x,y,scale);}};
客户端:10万棵树,内存只占5个模型
intmain(){TreeModelFactory factory;vector<TreeInstance>forest;// 生成10万棵树,只创建2种共享模型for(inti=0;i<100000;++i){string type=(i%2==0)?"Pine":"Oak";forest.push_back({float(i%1000),float(i/1000),0.8f+(i%3)*0.2f,factory.getModel(type)});}cout<<"\n=== 开始渲染森林 ===\n";for(inti=0;i<10;++i){// 只渲染前10棵演示forest[i].render();}cout<<"... 剩余99990棵树同样共享模型,内存爆炸?不存在的!\n";}

输出:

[工厂] 创建新共享模型: Pine [工厂] 创建新共享模型: Oak === 开始渲染森林 === [共享模型] 松树 @ (0,0) 缩放:0.8 [共享模型] 橡树 @ (1,0) 缩放:1 [共享模型] 松树 @ (2,0) 缩放:1.2 ...
C++ 真实项目里无处不在
  • 游戏引擎:Unreal的Foliage系统、Unity的Instancing渲染(共享Mesh和Material)
  • 文字渲染:每个字符(A~Z)只存一份Glyph(字体轮廓),成千上万文字实例共享
  • 粒子系统:10万粒子共享几种粒子纹理和行为
  • UI图标:整个App共享一套图标纹理图集(Texture Atlas)
  • Qt/OpenGL:共享VAO/VBO、Shader程序
经典坑 & 正确姿势
  • 内在状态必须不可变(共享对象不能被单个实例修改)
  • 外在状态由客户端持有(位置、颜色、缩放等)
  • 享元工厂通常是单例或静态
终极口诀(游戏开发者专属)

“千树万树同一模,内在共享外在独;
内存爆炸不存在,享元工厂真牛逼!”

刻在DNA里的一句话

当你面对“大量相似细粒度对象”(游戏实体、字符、粒子、图块),且内在状态远大于外在状态时,
立刻上享元模式——用工厂缓存共享对象,内存从GB降到MB!

现在,享元模式彻底说透了!
结构型模式还剩最后一篇:代理模式(Proxy)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/30 0:15:14

BGP思维导图

一、BGP基础二、BGP选路及属性三、BGP功能

作者头像 李华
网站建设 2026/2/5 1:05:35

comsol锂枝晶模型 Comsol 锂枝晶生长模型,锂枝晶生长,锂离子浓度分布

comsol锂枝晶模型 Comsol 锂枝晶生长模型&#xff0c;锂枝晶生长&#xff0c;锂离子浓度分布&#xff0c;电势分布 此链接是随机形核生长锂电池实验室里最让人头疼的玩意就是锂枝晶。这货像金属胡须一样野蛮生长&#xff0c;动不动就刺穿隔膜搞短路。去年用COMSOL建锂枝晶模型时…

作者头像 李华
网站建设 2026/2/5 18:10:05

高效文档转换利器:Dolphin智能解析工具使用指南

高效文档转换利器&#xff1a;Dolphin智能解析工具使用指南 【免费下载链接】Dolphin 项目地址: https://gitcode.com/GitHub_Trending/dolphin33/Dolphin 在处理大量PDF文档和学术论文时&#xff0c;传统的复制粘贴方式耗时耗力&#xff0c;而Dolphin文档智能解析工具…

作者头像 李华
网站建设 2026/2/5 22:40:53

IntelliJ IDEA 设置导出与导入完整指南(备份 / 迁移 / 团队共享)

在使用 IntelliJ IDEA&#xff08;简称 IDEA&#xff09;开发时&#xff0c;我们常会自定义快捷键、代码风格、主题等配置。为了避免重装 IDE、更换电脑后重复配置&#xff0c;或实现团队开发环境统一&#xff0c;掌握设置的导出与导入技巧至关重要。本文详细讲解两种核心场景的…

作者头像 李华
网站建设 2026/2/5 5:17:14

EmotiVoice在儿童玩具问答系统中的活泼语音表现

EmotiVoice在儿童玩具问答系统中的活泼语音表现 在智能玩具越来越“懂孩子”的今天&#xff0c;一个关键问题正被重新定义&#xff1a;机器该以什么样的声音与孩子对话&#xff1f; 过去&#xff0c;我们习惯了电子宠物里那种机械重复、毫无起伏的“机器人腔”。它能回答“11等…

作者头像 李华
网站建设 2026/2/5 15:17:12

EmotiVoice语音活力指数调节适应不同受众

EmotiVoice语音活力指数调节适应不同受众 在虚拟偶像直播中突然“破防”大笑&#xff0c;在儿童教育APP里用温柔语调讲故事&#xff0c;又能在紧急警报时瞬间切换成铿锵有力的播报声——这不再是科幻电影中的桥段&#xff0c;而是当下情感化TTS技术正在实现的真实交互体验。随着…

作者头像 李华