篇十一:享元模式:共享细粒度对象
篇十一:“享元模式:共享细粒度对象”
设计模式是软件开发中的重要工具,享元模式(Flyweight Pattern)是结构型设计模式的一种。享元模式旨在通过共享细粒度的对象,减少内存消耗和提高性能。在设计模式学习中,享元模式是一个重要的概念。本文将介绍享元模式的原理和优点,并提供C++实现享元模式的示例代码。
开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/。
另外有2本不错的关于设计模式的资料,分享出来与大家学习参考。
链接:https://pan.baidu.com/s/1RmhQF_o1CdK8U7s5KeILog?pwd=xc6d
提取码:xc6d
1. 享元模式的原理:
享元模式是一种结构型设计模式,其核心思想是通过共享细粒度的对象,减少内存消耗和提高性能。在软件开发中,有些对象可能会重复创建,造成内存资源的浪费。享元模式通过维护一个对象池来管理这些细粒度的对象,当需要创建对象时,先从对象池中查找是否已经存在该对象,如果存在则直接返回,如果不存在则创建新的对象并加入对象池中。
享元模式中有两种对象:内部状态和外部状态。内部状态是可以共享的,不会随着外部环境的改变而改变;而外部状态是随着外部环境的改变而改变的,每个对象都有不同的外部状态。
2. 享元模式的优点:
- 减少内存消耗:通过共享细粒度的对象,减少了内存的消耗,提高了系统的性能。
- 提高性能:共享对象减少了对象的创建和销毁过程,提高了系统的性能。
- 支持大量细粒度对象:享元模式适用于大量细粒度对象的场景,将对象的内部状态共享,节省了内存空间。
3. 在C++中使用享元模式:
a. 定义享元类:
// Flyweight.h
#include <string>class Flyweight {
public:virtual ~Flyweight() {}virtual void operation(const std::string& extrinsicState) const = 0;
};
b. 创建具体享元类:
// ConcreteFlyweight.h
#include "Flyweight.h"
#include <iostream>class ConcreteFlyweight : public Flyweight {
public:void operation(const std::string& extrinsicState) const override {std::cout << "Concrete Flyweight with extrinsic state: " << extrinsicState << std::endl;}
};
c. 创建享元工厂类:
// FlyweightFactory.h
#include "Flyweight.h"
#include <unordered_map>class FlyweightFactory {
public:Flyweight* getFlyweight(const std::string& key) {if (flyweights_.find(key) == flyweights_.end()) {flyweights_[key] = new ConcreteFlyweight();}return flyweights_[key];}private:std::unordered_map<std::string, Flyweight*> flyweights_;
};
d. 使用享元模式:
// main.cpp
#include "Flyweight.h"
#include "ConcreteFlyweight.h"
#include "FlyweightFactory.h"int main() {FlyweightFactory factory;Flyweight* flyweight1 = factory.getFlyweight("shared");flyweight1->operation("state1");Flyweight* flyweight2 = factory.getFlyweight("shared");flyweight2->operation("state2");return 0;
}
在上述示例中,我们首先定义了享元类Flyweight
,其中包含了操作的抽象接口operation()
。然后,我们创建了具体享元类ConcreteFlyweight
,实现了operation()
接口,表示可以共享的细粒度对象。接着,我们创建了享元工厂类FlyweightFactory
,用于管理享元对象的创建和共享。
在main.cpp
中,我们创建了享元工厂的实例factory
,通过调用factory.getFlyweight()
方法来获取享元对象。当需要创建对象时,首先查找是否已经存在相应的享元对象,如果存在则直接返回,如果不存在则创建新的对象。最后,我们调用flyweight1->operation()
和flyweight2->operation()
来演示享元对象的使用。
4. 享元模式的代码解析:
- 享元模式通过共享细粒度的对象,减少内存消耗和提高性能。
- 共享对象分为内部状态和外部状态,内部状态是可以共享的,不随外部环境变化而变化;外部状态是随外部环境变化而变化的,每个对象都有不同的外部状态。
- 享元模式适用于大量细粒度对象的场景,通过维护一个对象池来管理共享对象。
5. 总结:
享元模式是一种有用的设计模式,通过共享细粒度的对象,减少内存消耗和提高性能。在C++中,我们可以通过定义享元类、具体享元类和享元工厂类来应用享元模式。通过享元模式,我们可以有效地支持大量细粒度对象,并节省内存资源。享元模式的应用场景很多,例如在图形编辑器、文本编辑器或操作系统中都可以使用享元模式来优化性能。
希望本文能够帮助您深入理解享元模式的原理和优点,并通过C++的示例代码演示了如何实现享元模式。在后续的专栏文章中,我们将继续介绍更多设计模式的知识,包括原理、详细介绍、示例代码和代码解析,帮助您深入学习和应用设计模式。
参考文献:
-
Gamma, E., Helm, R., Johnson, R., & Vlissides,J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley Professional.
- C++ Core Guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
6. 注意事项:
在使用享元模式时,需要注意以下几点:- 区分内部状态和外部状态:在设计享元类时,需要区分哪些状态是内部状态可以共享的,哪些状态是外部状态随外部环境变化而变化的。确保在共享对象时,只共享内部状态,而外部状态是客户端负责传递的。
- 线程安全性:如果享元对象在多线程环境下被并发访问,需要考虑线程安全性。可以使用锁机制或其他并发控制方法来保证共享对象的线程安全性。
- 对象池管理:对象池的管理也需要考虑合适的策略,避免对象池过大导致内存浪费,或过小导致频繁的对象创建和销毁。
7. 总结:
享元模式是一种重要的设计模式,通过共享细粒度的对象,减少内存消耗和提高性能。在C++中,我们可以通过定义享元类、具体享元类和享元工厂类来应用享元模式。通过享元模式,我们可以支持大量细粒度对象,并节省内存资源。享元模式在图形编辑器、文本编辑器、操作系统等领域都有广泛的应用,能够优化系统性能,提升用户体验。希望本文能够帮助您深入理解享元模式的原理和优点,并通过C++的示例代码演示了如何实现享元模式。设计模式是软件开发中的重要知识,掌握不同的设计模式有助于提高代码质量、可维护性和可扩展性。在后续的专栏文章中,我们将继续介绍更多设计模式的知识,包括原理、详细介绍、示例代码和代码解析,帮助您深入学习和应用设计模式。
如果您有其他需求或主题的建议,请随时告诉我,我将为您提供更多的帮助!
参考文献:
- Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley Professional.
- C++ Core Guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
感谢您的阅读,欢迎一起探讨,共同进步,推荐大家使用学习助手AIRight来解答学习过程中的问题,访问链接:http://airight.fun/
相关文章:
![](https://www.ngui.cc/images/no-images.jpg)
篇十一:享元模式:共享细粒度对象
篇十一:“享元模式:共享细粒度对象” 设计模式是软件开发中的重要工具,享元模式(Flyweight Pattern)是结构型设计模式的一种。享元模式旨在通过共享细粒度的对象,减少内存消耗和提高性能。在设计模式学习中…...
![](https://img-blog.csdnimg.cn/d2dee03bca4848b49f7d12016555d920.png)
Dev控件 Gridcontrol,gridview 实现多选功能
在网上看了好多实现dev控件GridControl多选功能的方法,都很麻烦,其实GridControl有一个自带的实现多选功能的控件,很简单。 实现效果如下 无需代码代码,使用GridControl中自带的多选功能,在界面直接设置即可 1.找到要…...
![](https://img-blog.csdnimg.cn/img_convert/d57474be6ac57eddecf8bfd92b74d120.png)
内网穿透:如何通过公网访问本地Web服务器?
文章目录 前言1. 首先安装PHPStudy2.下载一个开源的网页文件3. 选择“创建网站”并将网页内容指向下载好的开源网页文件4. 打开本地网页5. 打开本地cpolar客户端6. 保存隧道设置 生成数据隧道 前言 随着科技进步和时代发展,计算机及互联网已经深深融入我们的生活和…...
![](https://img-blog.csdnimg.cn/2077ae62960c4ce8a30c1ce438b61214.png)
在qemu中挂载镜像文件
将镜像文件作为交换分区 创建镜像文件: dd if/dev/zero ofswap.img bs512 count131072 qemu-system-arm -nographic -M vexpress-a9 -m 64M -kernel arch/arm/boot/zImage -append "rdinit/linuxrc consolettyAMA0 loglevel8" -dtb arch/arm/boot/dts/…...
![](https://img-blog.csdnimg.cn/cf3ded6c7b57413794e9c925db009bfc.png)
报错注入(主键重复)攻击原理
基本原理 利用数据表中主键不能重复的特点,通过构造重复的主键,使得数据库报错,并将报错结果返回到前端。 SQL说明函数 以pet数据表为例进行说明 rond(): 返回[0,1)区间内的任意浮点数。 count(): 返回每个组的列行数。 如࿰…...
![](https://www.ngui.cc/images/no-images.jpg)
Golang基础教程
Golang基础教程 golang简介安装golanggolang开发工具go常用命令golang开发 vscode快捷键如何编写golang代码golang标识符、关键字、命名规则golang变量go语言常量go语言数据类型go语言布尔类型go语言数字类型golang字符串golang格式化输出golang运算符go语言中的流程控制golan…...
![](https://img-blog.csdnimg.cn/img_convert/a74208095bd1fad10b4fd1107f00fc04.jpeg)
ppt压缩文件怎么压缩最小?文件压缩技巧分享
在日常的工作和学习中,难免会遇到PPT太大,需要将其压缩变小的情况,但很多朋友还不知道怎么压缩PPT文件,下面就给大家分享几个简单的方法,分分钟缩小过大的PPT文件。 一、PowerPoint PowerPoint就是微软公司的演示文稿…...
![](https://img-blog.csdnimg.cn/73497a5c00864ac9ab1d52bd58439af9.png)
实例033 制作闪烁的窗体
实例说明 Windows系统中,当程序在后台运行时,如果某个窗口的提示信息需要用户浏览,该窗口就会不停的闪烁,这样就会吸引用户的注意。同样,如果在自己的程序中使某个窗口不停的闪烁就会吸引用户的注意。本例设计了一个闪…...
![](https://img-blog.csdnimg.cn/f847189b472c436caf5053fd96a8c8ea.png)
【JavaEE进阶】Spring创建与使用
文章目录 一. 创建 Spring 项目1.1 创建一个Maven项目1.2 添加Spring依赖1.4. 创建一个启动类 二. 将 Bean 对象存放至 Spring 容器中三. 从 Spring 容器中读取到 Bean1. 得到Spring对象2. 通过Spring 对象getBean方法获取到 Bean对象【DI操作】 一. 创建 Spring 项目 接下来使…...
![](https://img-blog.csdnimg.cn/img_convert/f876f16a0a39b1eeb5abdf8cd09cebbc.png)
PHP8的循环控制语句-PHP8知识详解
我们在上一节讲的是条件控制语句,本节课程我们讲解循环控制语句。循环控制语句中,主要有for循环、while循环、do...while循环和foreach循环。 在编写代码时,经常需要反复运行同一代码块。我们可以使用循环来执行这样的任务,而不是…...
![](https://www.ngui.cc/images/no-images.jpg)
第八次作业
一,.什么是数据认证,有什么作用,有哪些实现的技术手段? 数据认证是指保证数据的真实性、完整性和可信度,以确保数据不被篡改或伪造。其作用包括但不限于: 保护关键数据不被恶意篡改或损坏 提供数据来源的可靠性和安全…...
![](https://www.ngui.cc/images/no-images.jpg)
LeetCode //C - 290. Word Pattern
290. Word Pattern Given a pattern and a string s, find if s follows the same pattern. Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in s. Example 1: Input: pattern “abba”, s “dog c…...
![](https://img-blog.csdnimg.cn/334a300fd3d04f6f9bee541b7cbeed9f.png)
[保研/考研机试] 括号匹配问题 C++实现
题目描述: 在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来的字符串&am…...
![](https://img-blog.csdnimg.cn/56ce8601aa9b444fbdd699dfa8a66080.png)
springBoot集成caffeine,自定义缓存配置 CacheManager
目录 springboot集成caffeine Maven依赖 配置信息:properties文件 config配置 使用案例 Caffeine定制化配置多个cachemanager springboot集成redis并且定制化配置cachemanager springboot集成caffeine Caffeine是一种基于服务器内存的缓存库。它将数据存储在…...
![](https://img-blog.csdnimg.cn/521646f4450146939b60adc71609e4b9.png)
【瑞吉外卖】Git部分学习
Git简介 Git是一个分布式版本控制工具,通常用来对软件开发过程中的源代码文件进行管理。通过Git仓库来存储和管理这些文件,Git仓库分为两种: 本地仓库:开发人员自己电脑上的Git仓库 远程仓库:远程服务器上的Git仓库…...
![](https://www.ngui.cc/images/no-images.jpg)
如何阐述自己做了一个什么样的东西
线上qps2000,主要的性能瓶颈在于出现在数据库I/O上。另外,如果是一个正常部署的容器,qps能达到几百就不错了。资讯服务现在做了静态的底层页,所以热点新闻多数会命中底层页,即便没有命中底层页,也会走多层的…...
![](https://www.ngui.cc/images/no-images.jpg)
TC3XX - MCAL知识点(二十二):QSPI 同步与异步 Mcal配置及代码实战
目录 1、MCAL配置 1.1、配置目标 1.2、同步QSPI配置 1.2.1、SpiGeneral 1.2.2、SpiMaxChannel 1.2.3、SpiMaxJob...
![](https://img-blog.csdnimg.cn/img_convert/2222037583dfd54ac21fcf6c4bf006f6.png)
led台灯哪些牌子性价比高?推荐几款性价比高的护眼台灯
作为学龄期儿童的家长,最担心的就是孩子长时间学习影响视力健康。无论是上网课、写作业、玩桌游还是陪伴孩子读绘本,都需要一个足够明亮的照明环境,因此选购一款为孩子视力发展保驾护航的台灯非常重要。为大家推荐几款性价比高的护眼台灯。 …...
![](https://www.ngui.cc/images/no-images.jpg)
什么情况下容易发生锁表及如何处理
目录 什么情况下容易发生锁表发生锁表怎么解决 什么情况下容易发生锁表 在数据库中,当多个事务同时竞争访问同一个表的资源时,可能会发生锁表现象,导致性能下降甚至阻塞。以下情况容易导致锁表问题: 大事务操作:如果一…...
![](https://img-blog.csdnimg.cn/e90adc1f769748c99cbf640e205422c1.png)
elk开启组件监控
elk开启组件监控 效果: logstash配置 /etc/logstash/logstash.yml rootnode1:~# grep -Ev "^#|^$" /etc/logstash/logstash.yml path.data: /var/lib/logstash path.logs: /var/log/logstash xpack.monitoring.enabled: true xpack.monitoring.elasti…...
![](https://img-blog.csdnimg.cn/abec0da97bc4451fb1a2b975417dc32f.jpeg#pic_center)
Java Random 类的使用
Java中的Random类是用来生成伪随机数的工具类。它可以用来生成随机的整数、浮点数和布尔值。以下是Java Random类的一些常见用法: 创建Random对象: Random random new Random();生成随机整数: int randomNumber random.nextInt(); // 生…...
![](https://img-blog.csdnimg.cn/46aba8174d604ccc9a6d9eff62d2a7b2.png)
完美的分布式监控系统——Prometheus(普罗米修斯)与优雅的开源可视化平台——Grafana(格鲁夫娜)
一、基本概念 1、之间的关系 prometheus与grafana之间是相辅相成的关系。作为完美的分布式监控系统的Prometheus,就想布加迪威龙一样示例和动力强劲。在猛的车也少不了仪表盘来观察。于是优雅的可视化平台Grafana出现了。 简而言之Grafana作为可视化的平台ÿ…...
![](https://img-blog.csdnimg.cn/6c5b8e2f4b6347b4a5dffe9a65614b53.png)
pycharm的Terminal中如何设置打开anaconda3的虚拟环境
在pycharm的File -> Settings -> Tools -> Terminal下面,如下图所示 修改为红框中内容,然后关闭终端在重新打开终端,即可看到anaconda3的虚拟环境就已经会被更新...
![](https://img-blog.csdnimg.cn/c1cd80f8473e48e39d2b36fb95a30378.png)
Jmeter(四) - 从入门到精通 - 创建网络测试计划(详解教程)
1.简介 在本节中,您将学习如何创建基本的 测试计划来测试网站。您将创建五个用户,这些用户将请求发送到JMeter网站上的两个页面。另外,您将告诉用户两次运行测试。因此,请求总数为(5个用户)x(2…...
![](https://img-blog.csdnimg.cn/10dc605fd8c4478398e7ed3be4bf7899.png)
Flowable-结束事件-空结束事件
目录 定义图形标记XML内容 定义 空结束事件是最常见的一种结束事件,也是最简单的一种结束事件,只要把结束任务置于流程 或分支的最后节点,流程实例运行到该节点的时候,流程引擎就会结束该流程实例或分支。前面提 到,结…...
![](https://img-blog.csdnimg.cn/6bcc2aca3f6a4a0ca36991dbe259314e.png)
Elasticsearch:如何创建 Elasticsearch PEM 和/或 P12 证书?
你是否希望使用 SSL/TLS 证书来保护你的 Elasticsearch 部署? 在本文中,我们将指导你完成为 Elasticsearch 创建 PEM 和 P12 证书的过程。 这些证书在建立安全连接和确保 Elasticsearch 集群的完整性方面发挥着至关重要的作用。 友情提示:你可…...
![](https://img-blog.csdnimg.cn/504599a4ebee4bc7a7d7121d41a9f900.png#pic_center)
数仓架构模型设计参考
1、数据技术架构 1.1、技术架构 1.2、数据分层 将数据仓库分为三层,自下而上为:数据引入层(ODS,Operation Data Store)、数据公共层(CDM,Common Data Model)和数据应用层ÿ…...
![](https://www.ngui.cc/images/no-images.jpg)
RedisTemplate.opsForGeo()用法简介并举例
RedisTemplate.opsForGeo()是RedisTemplate类提供的用于操作Geo类型(地理位置)的方法。它可以用于对Redis中的Geo数据结构进行各种操作,如添加地理位置、获取距离、获取位置信息等。 下面是一些常用的RedisTemplate.opsForGeo()方法及其用法…...
![](https://img-blog.csdnimg.cn/1423b68274fd42a5a0b288922d07887f.png)
Android OkHttp源码分析--拦截器
拦截器责任链: OkHttp最核心的工作是在 getResponseWithInterceptorChain() 中进行,在进入这个方法分析之前,我们先来了 解什么是责任链模式,因为此方法就是利用的责任链模式完成一步步的请求。 拦截器流程: OkHtt…...
![](https://www.ngui.cc/images/no-images.jpg)
docker:如何传环境变量给entrypoint
使用shell,不带中括号 ENTRYPOINT .\main -web -c $CONFIGENTRYPOINT [sh, -c, ".\main -web -c $CONFIG"]docker build --build-arg ENVIROMENTintegration // 覆盖ENTRYPOINT命令 使用shell脚本 ENTRYPOINT ["./entrypoint.sh"]entrypoint.sh 镜像是a…...
![](/images/no-images.jpg)
永久免费的cad软件/广州营销seo
设计模式的定义 设计模式(Design Pattern)是一套面向对象的代码设计经验总结。 设计模式是一种思想,也是一种技术。 一种设计模式就是一种解决实际问题的方案。 每一种设计模式虽然有既定的结构图和基本程序代码,但是应该不局限于…...
![](https://www.cnblogs.com/Emoticons/face/043.gif)
大连网站制作的/关键词搜索引擎
原来在家里的网络被偷了以后,电信的就一直没有来修理,说他们的修理费太高,决定把我们这里定为黑名单,也就是说在也不能通网络了,郁闷了。。。本来工作的地方离家就很远,骑电单车要120分钟,一天4…...
![](https://img-blog.csdnimg.cn/20190331131647801.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3VoYW84ODQxMDIzNA==,size_16,color_FFFFFF,t_70)
wordpress animate css/厦门网络推广
前言 Zuul 是Netflix 提供的一个开源组件,致力于在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。也有很多公司使用它来作为网关的重要组成部分,碰巧今年公司的架构组决定自研一个网关产品,集动态路由&#…...
![](/images/no-images.jpg)
郑州网站建设方案报价/网上做广告推广
在phpmyadmin中显示上传文件最大问8M,可我的单个sql文件超过50M,尝试上传,上传依然可以进行,但上传到8M即操作终止,phpmyadmin提示上传失败。该问题实际上是php的配置问题,在php.ini中有两个参数需要关注&a…...
![](/images/no-images.jpg)
电商网站建设思维导图/河南seo外包
该文章是系列文章 基于.NetCore和ABP框架如何让Windows服务执行Quartz定时作业 的其中一篇。 Windsor是ABP框架自带的IOC容器。 关于什么是IOC,你可以Bing或者Google一下,英文不错的话推荐看一看 https://www.tutorialsteacher.com/ioc。 更多关于Castle…...
![](https://img2018.cnblogs.com/blog/1491217/201903/1491217-20190320234635696-1867311168.png)
网站制作公司 沈阳/昆明排名优化
admin是django提供的基于web的管理数据库的工具,它是django.contrib 的一部分,可以在项目的settings.py中的INSTALLED_APPS看到。 一、admin管理工具的使用方法如下: 1.在models.py中创建模型 class Students(models.Model):snamemodels.Char…...