设计模式--享元模式

引言

享元模式(Flyweight Pattern)作为一种高效节省内存的结构型设计模式,其核心在于通过共享技术有效支持大量细粒度对象的重用,从而减少内存占用,提高系统性能。特别是在处理大量相似对象的场景下,享元模式通过区分内部状态(Intrinsic State)和外部状态(Extrinsic State),使得共享成为可能。本文将深入探讨享元模式的应用场景、使用技巧、注意事项,并通过C++11标准代码示例展示其实现细节。

应用场景
  • 大量相似对象:当系统需要创建大量相似或相同的对象,且这些对象大部分状态可以共享时。
  • 内存敏感应用:对于内存资源有限或者需要高度优化内存使用的应用。
  • 图形渲染:如游戏中的子弹、图标等,大量重复的元素可以通过享元模式减少内存占用。
  • 字符串处理:如编译器中的符号表,通过共享字符或字符串实例减少内存消耗。
使用技巧与注意事项
  1. 区分内外状态:明确哪些状态可以共享(内部状态),哪些需要外部控制(外部状态)。
  2. 状态独立性:确保内部状态不会随环境改变,外部状态由客户端维护,不影响享元对象的共享。
  3. 工厂模式结合:通常与工厂模式结合使用,以管理享元对象的创建和获取,确保共享逻辑的透明性。
  4. 缓存管理:合理设计享元池(Flyweight Pool)来缓存和管理享元对象,提高重用效率。
C++11代码示例:文字渲染系统

假设我们正在设计一个文本编辑器的文字渲染系统,其中大量的字符对象具有相同的字体和颜色属性,但位置不同。通过享元模式,我们可以有效减少字符对象的创建。

#include <iostream>
#include <unordered_map>
#include <memory>
#include <string>// 享元接口
class Character {
public:virtual ~Character() {}virtual void display(int x, int y) const = 0;
};// 具体享元角色
class ConcreteCharacter : public Character {
public:ConcreteCharacter(char c, const std::string& font, int fontSize, const std::string& color): character_(c), font_(font), fontSize_(fontSize), color_(color) {}void display(int x, int y) const override {std::cout << "Rendering character '" << character_ << "' at (" << x << ", " << y << ") with font " << font_ << ", size " << fontSize_ << ", color " << color_ << std::endl;}private:char character_;std::string font_;int fontSize_;std::string color_; // 内部状态
};// 享元工厂
class CharacterFactory {
public:std::shared_ptr<Character> getCharacter(char c, const std::string& font, int fontSize, const std::string& color) {std::string key = std::to_string(c) + font + std::to_string(fontSize) + color;if (pool_.find(key) == pool_.end()) {pool_[key] = std::make_shared<ConcreteCharacter>(c, font, fontSize, color);}return pool_[key];}private:std::unordered_map<std::string, std::shared_ptr<Character>> pool_;
};int main() {CharacterFactory factory;// 创建多个相同属性但位置不同的字符对象auto charA = factory.getCharacter('A', "Arial", 12, "Black");charA->display(10, 20);auto charB = factory.getCharacter('B', "Arial", 12, "Black");charB->display(30, 40);return 0;
}

在这个C++11代码示例中,Character接口定义了享元对象的行为,而ConcreteCharacter实现了具体的字符渲染逻辑,包含了字符的内部状态(如字体、大小、颜色)。CharacterFactory作为享元工厂,负责管理享元对象的创建和缓存,通过使用std::unordered_mapstd::shared_ptr智能指针,确保了共享实例的高效管理,同时避免了内存泄漏的问题。此例展示了如何通过享元模式有效减少相似对象的内存占用,特别是在需要大量创建对象的场景下,能显著提升程序性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/14408.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智慧监狱人员行为识别监测系统

智慧监狱人员行为识别监测系统是基于神经网络AI视觉智能分析算法开发的技术。智慧监狱人员行为识别监测系统利用现场监控摄像头&#xff0c;通过对人体活动骨架的结构化分析&#xff0c;根据人体运动轨迹定义了多种异常行为&#xff0c;从而实现对监舍内的静坐不动、离床、攀高…

Tron节点监控脚本使用说明

文章目录 一、配置二、脚本编写2.1 Python脚本--监控节点是否正在同步2.1.1 pyton脚本脚本示例2.1.2 使用说明2.2.3 脚本监控内容说明 2.2 Shell脚本--综合情况监控2.2.1 shell脚本示例2.2.2 使用说明2.2.3 脚本监控内容说明 最近搭建了TRON节点&#xff0c;为了防止节点在生产…

Mixiy(米思齐)安装

Mixiy(米思齐)安装 官网地址&#xff1a;爱上米思齐 打开官网&#xff0c;选择下图的软件进行下载 复制提取码&#xff0c;点击链接跳转到网盘进行下载&#xff0c;选择(RC4完整版) 下载完成后&#xff0c;解压到合适的位置&#xff0c;进入文件夹&#xff0c;双击Mixly.exe即…

Docker 部署Jenkins

1、运行镜像 docker run --namejenkins \--restartalways \--privilegedtrue \-u root \-p 8080:8080 \-p 50000:50000 \-v /home/docker/jenkins/jenkins_home:/var/jenkins_home \-v /usr/bin/docker:/usr/bin/docker \-v /var/run/docker.sock:/var/run/docker.sock \-e TZ…

【Crypto】MD5

文章目录 MD5解题感悟 MD5 提示的很明显MD5 小小flag&#xff0c;拿下&#xff01; 解题感悟 没啥感悟…

Java输入与输出详解

Java输入和输出 前言一、Java打印Hello World二、输出到控制台基本语法代码示例格式化字符串 三、从键盘输入读入一个字符正确写法 使用 Scanner 读取字符串/整数/浮点数使用 Scanner 循环读取 N 个数字 前言 推荐一个网站给想要了解或者学习人工智能知识的读者&#xff0c;这…

使用 Java 和 MyBatis 实现动态排序的多表查询

相关 java实现一个根据字段和排序方式进行排序 java实现自定义排序 自定义动态排序 前言 在Web开发中&#xff0c;前端通常会传递一些参数来决定数据的排序方式&#xff0c;例如排序字段和排序方向。本文将展示如何在 Java 项目中结合 MyBatis 实现动态排序&#xff0c;尤其…

MySQL-性能分析

1、数据库服务器的优化步骤 2、查看系统性能参数 可以使用show status语句查询一些MySQL数据库服务器的性能参数 执行频率语法格式&#xff1a;show [ global | session ] status like 参数 &#xff1b;常用性能参数如下所示 参数名说明connection连接MySQL服务器的次数upti…

Autodesk 3ds Max下载,3ds MAX 2024三维建模渲染软件安装包下载安装

3ds MAX中文版&#xff0c;其强大的功能和灵活的操作为广大用户提供了无限的创意空间&#xff0c;使得高质量动画、最新游戏、设计效果等领域的制作需求得以完美满足。 ​ 作为一款三维建模软件&#xff0c;3ds MAX中文版具备极高的建模精度和渲染质量。它支持多种建模方式&am…

【Fiddler抓包工具】第四节.断点设置和弱网测试

文章目录 前言一、断点设置 1.1 全局断点 1.2 局部断点 1.3 打断点的几种常用命令 1.4 篡改响应报文二、弱网测试 2.1 网络限速 2.2 精准限速总结 前言 一、断点设置 1.1 全局断点 特点&#xff1a; 中断Fiddler捕获的所有请求&#xff0c;包括…

记录一次prometheus因时区不同导致的无法获取数据问题

一、故障出现原因 prometheus机器压力过大&#xff0c;内存耗尽&#xff0c;负载飙高&#xff0c;导致无法登录&#xff1b; 于是从公有云web界面进行重启&#xff0c;重启后内存还是不足&#xff0c;负载很快升高&#xff1b; 对机器进行配置变更&#xff0c;由4C8G升级为4…

在链游中,智能合约如何被用于实现游戏内的各种功能

随着区块链技术的快速发展&#xff0c;链游&#xff08;Blockchain Games&#xff09;作为区块链技术的重要应用领域之一&#xff0c;正逐渐展现出其独特的魅力和优势。其中&#xff0c;智能合约作为链游的核心技术之一&#xff0c;对于实现游戏内的各种功能起到了至关重要的作…

【C++初阶】—— 类和对象 (下)

&#x1f4dd;个人主页&#x1f339;&#xff1a;EterNity_TiMe_ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 类和对象 1. 运算符重载运算符重载赋值运算符重载前置和后置重载 2. 成员函数的补充3. 初始化列…

Java的函数式接口和 Lambda 表达式

在 Java 8 中&#xff0c;可以通过使用函数式接口和 Lambda 表达式来实现类似 JavaScript 中将函数作为参数传递的功能。 以下是一个简单的示例&#xff0c;演示如何在 Java 中使用函数式接口将函数作为参数传递&#xff1a; 定义一个函数式接口&#xff08;函数式接口是只有…

CentOS上升级glibc2.17至glibc2.31

glibc是Linux系统中的重要组件之一。在CentOS中&#xff0c;glibc通常是作为系统的默认C标准库使用的&#xff0c;因为它是许多软件的基础库。在CentOS中&#xff0c;glibc的版本通常与CentOS版本一起发布。因为CentOS通常会优先选择稳定性而不是最新性&#xff0c;所以CentOS使…

Vue项目如何进行XSS防护

前言 在目前主推网络安全的情况下&#xff0c;很多开发项目都需要在上线前进行渗透测试&#xff0c;当符合渗透测试标准及没有安全漏洞即可正常上线&#xff0c;当前还会有代码审计的&#xff0c;这个另当别论。 如何对XSS进行防护 在很多的富文本编辑器项目中&#xff0c;x…

leecode热题100---994:腐烂的橘子

题目&#xff1a; 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b; 值 1 代表新鲜橘子&#xff1b; 值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回…

C++之第九课

课程列表 今天&#xff0c;我们要学习一种结构&#xff1a;循环结构。 循环的方法有3种。 今天先将第1种for学了&#xff1a; int a;//循环变量 int b; for(a1;a<10;a){//像if那样“打包”cout<<a<<" ";b; } 当然&#xff0c;也可以这样写&#…

【MySQL精通之路】InnoDB(5)-内存结构

总目录&#xff1a; 【MySQL精通之路】InnoDB存储引擎-CSDN博客 上一篇&#xff1a; 【MySQL精通之路】InnoDB(4)-架构图-CSDN博客 目录 ​编辑 1 缓存池&#xff08;Buffer Pool&#xff09; 1.1 缓存池LRU算法 1.2 缓存区配置 1.3 使用InnoDB标准监视器监视缓存池 …

SSRF服务端请求伪造漏洞原理与修复及靶场实践

SSRF服务端请求伪造漏洞原理与修复及靶场实践 SSRF漏洞原理与检测 SSRF&#xff08;Server-Side Request Forgery&#xff0c;服务器端请求伪造&#xff09;漏洞是一种因为服务端提供了远程访问服务&#xff0c;而并未对请求目标进行限制或限制不严格而引起的安全漏洞&#x…