篇十一:享元模式:共享细粒度对象
篇十一:“享元模式:共享细粒度对象”
设计模式是软件开发中的重要工具,享元模式(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/
相关文章:
篇十一:享元模式:共享细粒度对象
篇十一:“享元模式:共享细粒度对象” 设计模式是软件开发中的重要工具,享元模式(Flyweight Pattern)是结构型设计模式的一种。享元模式旨在通过共享细粒度的对象,减少内存消耗和提高性能。在设计模式学习中…...

Dev控件 Gridcontrol,gridview 实现多选功能
在网上看了好多实现dev控件GridControl多选功能的方法,都很麻烦,其实GridControl有一个自带的实现多选功能的控件,很简单。 实现效果如下 无需代码代码,使用GridControl中自带的多选功能,在界面直接设置即可 1.找到要…...

内网穿透:如何通过公网访问本地Web服务器?
文章目录 前言1. 首先安装PHPStudy2.下载一个开源的网页文件3. 选择“创建网站”并将网页内容指向下载好的开源网页文件4. 打开本地网页5. 打开本地cpolar客户端6. 保存隧道设置 生成数据隧道 前言 随着科技进步和时代发展,计算机及互联网已经深深融入我们的生活和…...

在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/…...

报错注入(主键重复)攻击原理
基本原理 利用数据表中主键不能重复的特点,通过构造重复的主键,使得数据库报错,并将报错结果返回到前端。 SQL说明函数 以pet数据表为例进行说明 rond(): 返回[0,1)区间内的任意浮点数。 count(): 返回每个组的列行数。 如࿰…...
Golang基础教程
Golang基础教程 golang简介安装golanggolang开发工具go常用命令golang开发 vscode快捷键如何编写golang代码golang标识符、关键字、命名规则golang变量go语言常量go语言数据类型go语言布尔类型go语言数字类型golang字符串golang格式化输出golang运算符go语言中的流程控制golan…...

ppt压缩文件怎么压缩最小?文件压缩技巧分享
在日常的工作和学习中,难免会遇到PPT太大,需要将其压缩变小的情况,但很多朋友还不知道怎么压缩PPT文件,下面就给大家分享几个简单的方法,分分钟缩小过大的PPT文件。 一、PowerPoint PowerPoint就是微软公司的演示文稿…...

实例033 制作闪烁的窗体
实例说明 Windows系统中,当程序在后台运行时,如果某个窗口的提示信息需要用户浏览,该窗口就会不停的闪烁,这样就会吸引用户的注意。同样,如果在自己的程序中使某个窗口不停的闪烁就会吸引用户的注意。本例设计了一个闪…...

【JavaEE进阶】Spring创建与使用
文章目录 一. 创建 Spring 项目1.1 创建一个Maven项目1.2 添加Spring依赖1.4. 创建一个启动类 二. 将 Bean 对象存放至 Spring 容器中三. 从 Spring 容器中读取到 Bean1. 得到Spring对象2. 通过Spring 对象getBean方法获取到 Bean对象【DI操作】 一. 创建 Spring 项目 接下来使…...

PHP8的循环控制语句-PHP8知识详解
我们在上一节讲的是条件控制语句,本节课程我们讲解循环控制语句。循环控制语句中,主要有for循环、while循环、do...while循环和foreach循环。 在编写代码时,经常需要反复运行同一代码块。我们可以使用循环来执行这样的任务,而不是…...
第八次作业
一,.什么是数据认证,有什么作用,有哪些实现的技术手段? 数据认证是指保证数据的真实性、完整性和可信度,以确保数据不被篡改或伪造。其作用包括但不限于: 保护关键数据不被恶意篡改或损坏 提供数据来源的可靠性和安全…...
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…...

[保研/考研机试] 括号匹配问题 C++实现
题目描述: 在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来的字符串&am…...

springBoot集成caffeine,自定义缓存配置 CacheManager
目录 springboot集成caffeine Maven依赖 配置信息:properties文件 config配置 使用案例 Caffeine定制化配置多个cachemanager springboot集成redis并且定制化配置cachemanager springboot集成caffeine Caffeine是一种基于服务器内存的缓存库。它将数据存储在…...

【瑞吉外卖】Git部分学习
Git简介 Git是一个分布式版本控制工具,通常用来对软件开发过程中的源代码文件进行管理。通过Git仓库来存储和管理这些文件,Git仓库分为两种: 本地仓库:开发人员自己电脑上的Git仓库 远程仓库:远程服务器上的Git仓库…...
如何阐述自己做了一个什么样的东西
线上qps2000,主要的性能瓶颈在于出现在数据库I/O上。另外,如果是一个正常部署的容器,qps能达到几百就不错了。资讯服务现在做了静态的底层页,所以热点新闻多数会命中底层页,即便没有命中底层页,也会走多层的…...
TC3XX - MCAL知识点(二十二):QSPI 同步与异步 Mcal配置及代码实战
目录 1、MCAL配置 1.1、配置目标 1.2、同步QSPI配置 1.2.1、SpiGeneral 1.2.2、SpiMaxChannel 1.2.3、SpiMaxJob...

led台灯哪些牌子性价比高?推荐几款性价比高的护眼台灯
作为学龄期儿童的家长,最担心的就是孩子长时间学习影响视力健康。无论是上网课、写作业、玩桌游还是陪伴孩子读绘本,都需要一个足够明亮的照明环境,因此选购一款为孩子视力发展保驾护航的台灯非常重要。为大家推荐几款性价比高的护眼台灯。 …...
什么情况下容易发生锁表及如何处理
目录 什么情况下容易发生锁表发生锁表怎么解决 什么情况下容易发生锁表 在数据库中,当多个事务同时竞争访问同一个表的资源时,可能会发生锁表现象,导致性能下降甚至阻塞。以下情况容易导致锁表问题: 大事务操作:如果一…...

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…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...