【设计模式之享元模式 -- C++】

享元模式 – 共享对象,节省内存

享元模式(Flyweight Pattern)是一种用于性能优化的模式,其核心是运用共享技术来有效支持大量细粒度的对象。享元模式可以避免大量非常相似类的开销。在程序设计中,有时我们需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是相同的,有时候就能够大幅度地减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时传递进来,就可以通过共享大幅度地减少单个实例的数目。

组成

享元工厂(FlyweightFactory):享元工厂是一个用于创建并管理享元对象的工厂类,它主要用来确保合理地共享享元,当用户请求一个享元时,享元工厂提供一个已创建的实例或者创建一个(如果不存在的话)。

抽象享元类(Abstract Flyweight):这是一个接口或抽象类,声明了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部状态,同时也可以通过这些方法来设置外部状态。

具体享元类(Concrete Flyweight):实现抽象享元类,并为内部状态增加存储空间。

非共享具体享元类(Unshared Concrete Flyweight):并非所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类。

客户类(Client):客户类持有一个对抽象享元类的引用,计算或存储一个(或多个)抽象享元类的外部状态。

在享元模式中,内部状态存

好处
  1. 它可以极大地减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份。
  2. 它可以防止大量相似类的开销,这样可以提高系统的性能。
缺点
  1. 它使得系统更加复杂,需要分离出内部状态和外部状态,而外部状态具有固化特性,一旦修改就可能会导致系统的行为异常。
使用场景
  1. 系统中存在大量的相似对象:享元模式通过共享技术实现相同或相似对象的重用。

  2. 这些对象消耗大量的内存:一些系统中,大量使用了对象,造成了大量的内存消耗,可以考虑使用享元模式。

  3. 对象的状态大部分可以外部化:享元模式把对象的属性划分为内部状态和外部状态,内部状态储存在享元对象内部,而外部状态应当由客户端来考虑。

  4. 清除对象的外部状态可以削减对象数量:如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

实现
  1. 创建一个享元工厂
class FlyweightFactory {
public:FlyweightFactory() {}~FlyweightFactory() {}// 获取享元对象Flyweight* GetFlyweight(string key) {if (m_flyweightMap.find(key) == m_flyweightMap.end()) {m_flyweightMap[key] = new ConcreteFlyweight();}return m_flyweightMap[key];}private:map<string, Flyweight*> m_flyweightMap;
};
  1. 享元基类
class Flyweight {
public:Flyweight() {}virtual ~Flyweight() {}virtual void Operation() = 0;
};
  1. 具体享元类
class ConcreteFlyweight : public Flyweight {
public:ConcreteFlyweight() {}~ConcreteFlyweight() {}void Operation() {cout << "ConcreteFlyweight Operation" << endl;}
};
  1. 不需要共享的享元类
class UnsharedConcreteFlyweight : public Flyweight {
public:UnsharedConcreteFlyweight() {}~UnsharedConcreteFlyweight() {}void Operation() {cout << "UnsharedConcreteFlyweight Operation" << endl;}
};

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

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

相关文章

vue-router 源码分析——6.命名路由

这是对vue-router 3 版本的源码分析。 本次分析会按以下方法进行&#xff1a; 按官网的使用文档顺序&#xff0c;围绕着某一功能点进行分析。这样不仅能学习优秀的项目源码&#xff0c;更能加深对项目的某个功能是如何实现的理解。这个对自己的技能提升&#xff0c;甚至面试时…

Python 围棋游戏【含Python源码 MX_008期】

简介&#xff1a; 围棋&#xff0c;源自中国&#xff0c;是一种两人对弈的策略棋类游戏。它被认为是世界上最复杂的棋类游戏之一&#xff0c;因为它的规则简单&#xff0c;但变化复杂多样。围棋的游戏目标是在棋盘上占领更多的地盘&#xff0c;并用自己的棋子围住对手的棋子&am…

docker-compose harbor 2.11

harbor 前言 “Harbor” 是一个用于管理容器镜像的开源仓库项目。由 VMware 开发和维护,Harbor 提供一个企业级的 Docker 镜像仓库,具有丰富的功能,包括: 镜像管理:提供存储和分发 Docker 镜像的能力。安全性:支持镜像签名和漏洞扫描,确保镜像的安全性。身份认证:集成…

项目代码导出到word脚本

需求 之前课程需求&#xff0c;需要将项目代码导出到一个word进行存档。当时就写了这个脚本来进行导出&#xff0c;现在毕业论文又有这个需求了&#xff0c;将这个脚本总结并帮助更多的人。 项目地址github项目&#xff0c;如果有人想更加完美的可以进行修改。 实现与操作 …

Android基础-JNI

一、JNI概述 JNI&#xff0c;全称Java Native Interface&#xff0c;是Java平台标准版&#xff08;Java SE Platform&#xff09;的一部分&#xff0c;它允许Java代码与其他语言写的代码进行交互。在Android系统中&#xff0c;JNI尤为重要&#xff0c;因为它连接了Java层与底层…

MySQL CDC

一、MySQL CDC概念 MySQL CDC&#xff08;Change Data Capture&#xff09;&#xff0c;即MySQL变更数据捕获&#xff0c;是一种能够捕获MySQL数据库中数据变化&#xff08;包括插入、更新和删除操作&#xff09;的技术。这些变化可以实时或准实时地同步到其他系统或服务中&am…

41 mysql subquery 的实现

前言 sub query 是一个我们经常会使用到的一个 用法 我们这里 看一看各个场景下面的 sub query 的相关处理 查看 本文, 需要 先看一下 join 的相关处理 测试数据表如下, 两张测试表, tz_test, tz_test03, 表结构 一致 CREATE TABLE tz_test (id int(11) unsigned NOT NUL…

vuex4.x 升级pinia,router 中使用同步组件导致项目启动失败

背景描述 升级的项目本来是vue2的项目&#xff0c;先升级成vue3&#xff0c;这个过程相关的问题都被决绝&#xff0c;当时状态管理使用的还是vuex4.x版本。 后面发现变成复杂模块时&#xff0c;后续再对复杂模块的功能进行迭代时&#xff0c;由于js的弱类型&#xff0c;改动时…

Python3 数据结构

列表 Python中列表是可变的&#xff0c;这是它区别于字符串和元组的最重要的特点&#xff0c;一句话概括即&#xff1a;列表可以修改&#xff0c;而字符串和元组不能。 以下是 Python 中列表的方法&#xff1a; 方法描述list.append(x)把一个元素添加到列表的结尾&#xff0…

管道(channel)和协程案例

请完成协程和管道协同工作的案例&#xff0c;具体要求&#xff1a; 1、开启一个writeData协程&#xff0c;向管道中写入50个整数 2、开启一个readData协程&#xff0c;从管道中读取writeData写入的数据 3、注意&#xff1a;writeData和readDate操作的是同一个管道 4、主线程需要…

0120__多字节字符vs宽字符

【字符集二】多字节字符vs宽字符-CSDN博客 多字节字符与宽字节字符_宽字符-CSDN博客

热门开源项目推荐:技术与地址概览

随着开源项目的不断兴起&#xff0c;越来越多的优秀项目涌现出来&#xff0c;为开发者们提供了丰富的资源和灵感。在此&#xff0c;我将为大家推荐几个热门的开源项目&#xff0c;并附上它们的开源地址&#xff0c;以供大家参考和了解。 1. TensorFlow 项目简介&#xff1a; …

Get、Post的区别------重定向和转发的区别-----http、https的区别!!!

一、Get和Post的区别 1、用途 Get&#xff1a;用于从服务器请求数据&#xff0c;幂等&#xff0c;不改变服务器的数据。Post&#xff1a;用于向服务器发送数据&#xff0c;可能改变服务器数据。 2、数据传输方式 Get&#xff1a;通过url传参&#xff0c;使用&符号连接多…

QT调用vs2019生成的c++动态库

QT调用vs2019生成的c动态库 dll库的创建方法&#xff1a; VS2019创建c动态链接库dll与调用方法-CSDN博客 加减法示范&#xff1a; 头文件 // 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLL3_EXPORTS // 符号编…

SurfaceView->SurfaceView基本概念

绘制过程 View和SurfaceView绘制过程 PhoneWindow&#xff1a;Window的具体实现&#xff0c;在Activity中调用setContentView()方法时&#xff0c;一个PhoneWindow实例会对应一个ViewRootImpl实例&#xff0c;绘制&#xff0c;事件分发传递给ViewRootImpl进行ViewRootImpl&…

少样本学习元学习

基本概念 首先是机器学习&#xff1a; 然后&#xff0c;什么是元学习&#xff08;what is meta learning?) 之前&#xff0c;Component都是让人自己设置的。在Meta Learning中&#xff0c;我们期望它能够自己学出来。 不同的meta learning方法就是想办法去学learning algori…

Python记忆组合透明度语言模型

&#x1f3af;要点 &#x1f3af;浏览器语言推理识别神经网络 | &#x1f3af;不同语言秽语训练识别数据集 | &#x1f3af;交互式语言处理解释 Transformer 语言模型 | &#x1f3af;可视化Transformer 语言模型 | &#x1f3af;语言模型生成优质歌词 | &#x1f3af;模型不确…

安卓兼容的编程语言有哪些:探索多样化的开发选择

安卓兼容的编程语言有哪些&#xff1a;探索多样化的开发选择 在安卓应用开发的世界里&#xff0c;编程语言的选择丰富多样&#xff0c;每一种语言都有其独特的优势和适用场景。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;深入剖析安卓兼容的编程语言&#xf…

【JavaScript脚本宇宙】探索前端图形与图像库:从2D图形到图像懒加载

优化用户体验&#xff1a;探究图像懒加载库的选择 前言 在Web开发中&#xff0c;图形和图像库扮演着至关重要的角色&#xff0c;它们可以让我们轻松地操作和呈现各种图形、图像以及数据可视化。本文将介绍一系列前端开发中常用的图形和图像库&#xff0c;从2D图形到3D图形&am…

指定文件停止git跟踪方法

1、当你已经将一个文件提交到Git仓库&#xff0c;然后将其添加到.gitignore文件中&#xff0c;但Git仍然跟踪该文件时&#xff0c;这是因为Git已经开始跟踪这个文件的历史。要让Git停止跟踪这个文件&#xff0c;你需要从Git的索引中显式地删除它。以下是解决这个问题的步骤&…