C++设计模式:享元模式(十一)

1、定义与动机
  • 概述:享元模式和单例模式一样,都是为了解决程序的性能问题。面向对象很好地解决了"抽象"的问题,但是必不可免得要付出一定的代价。对于通常情况来讲,面向对象的成本大豆可以忽略不计。但是某些情况,面向对象所带来的成本必须谨慎处理。

  • 定义:运用共享技术有效地支持大量细粒度的对象。

  • 动机:

    • 在软件系统中采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,而带来很高的运行时代价——主要指内存需求方面的代价。
    • 如何避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作?
  • 个人理解:例如在电脑中存在大量的字体

    • 首先:电脑在启动时不可能把所有的字体的文件渲染方式或者字体样式都加载到内存中,而应该是在需要的时候去加载

    • 其次:当电脑字体需要更改时会创建一个字体对象,而wps/office中的字体也会有一个对象字体。

    • 当word和ppt中的字体相同时,应该是只需要创建一个对象,因为字体这个东西应该说只读(只用来渲染,总不可能更改样式吧),因此这两个对象应该使用同一个对象即可,不应该在需要的地方就new!

    • 很明显这里也是解决一个性能问题的设计模式

    • 比较常见的一个实用地方:各种池子,线程池、内存池、连接池…,它们都应该创建好需要的时候去取一个就行,用完了还回去;而不是需要的时候new一个。

2、享元模式
  • 对于Font类创建出来的对象应该只能读,不允许修改
  • FontFactory字体工厂负责取字体,如果没有就new一个字体然后存放在一个数据结构中(这里用无序map)
#include <iostream>
#include <unordered_map>
#include <string>
class Font{
private:
    // unique object key
    std::string key;
    // object state ...
public:
    Font(const std::string &_key){
        // ...
    }
};

class FontFactory{
private:
    std::unordered_map<std::string, Font*> fontPool;
public:
    Font *GetFont(const std::string &key){
        if(fontPool.find(key) == fontPool.end()){
            Font *font = new Font(key);
            fontPool.insert(std::make_pair(key, font));
        }
        return fontPool[key];
    }
};

void process()
{
    FontFactory* fontFactory = new FontFactory();
    Font* songStyle = fontFactory->GetFont("宋体");
    Font* kaiStyle = fontFactory->GetFont("楷体");
    // ...
}

其实这里没有设计好:

  • FontFactory可以到处创建,可以考虑把FontFactory字体工厂做成一个单例的工厂。
  • 字体获取的多线程安全问题,准确来说获取应该是没有线程安全问题的,创建有…
3、总结
  • 面向对象很好的解决了抽象性问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight主要解决面向对象的代价问题,一般不初级面向队形的抽象性问题
  • Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象的状态处理(即只读不修改,否则后续可能无法重复使用)
  • 对象的数量太大从而导致对象内存开销加大——什么样的数量才算大?这需要仔细的根据具体应用情况进行评估,而不能凭空臆断。
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

程序“猿”自动化脚本(一)

1.剪贴板管理器&#x1f4cb; 您是否曾经发现自己在处理多个文本片段时忘记了复制的内容&#xff1f;有没有想过有一个工具可以跟踪您一天内复制的所有内容&#xff1f; 该自动化脚本会监视您复制的所有内容&#xff0c;将每个复制的文本无缝存储在时尚的图形界面中&#xff0c…

Salient Object Detection 探索经历

概述 显著性目标检测也被称为显著性检测&#xff0c;旨在通过模拟人类视觉感知系统来检测自然场景图像中最显著的目标和区域。虽然&#xff0c;显著性目标检测听名字是一个检测任务&#xff0c;但是实际上是一个图像分割任务&#xff0c;即一个像素级分类任务&#xff0c;是一…

【数组】5螺旋矩阵

这里写自定义目录标题 一、题目二、解题精髓-循环不变量三、代码 一、题目 给定⼀个正整数 n&#xff0c;⽣成⼀个包含 1 到 n^2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的正⽅形矩阵。 示例: 输⼊: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 二、解题精髓…

java包目录命名

包目录命名 config controller exception model common entity enums reponse request repository security service util

权限修饰符,代码块,抽象类,接口.Java

1&#xff0c;权限修饰符 权限修饰符&#xff1a;用来控制一个成员能够被访问的范围可以修饰成员变量&#xff0c;方法&#xff0c;构造方法&#xff0c;内部类 &#x1f47b;&#x1f457;&#x1f451;权限修饰符的分类 &#x1f9e3;四种作用范围由小到大(private<空着…

魔方网表ERP mailupdate.jsp 任意文件上传漏洞复现

0x01 产品简介 魔方网表ERP是一款高效、灵活的企业资源规划解决方案,旨在帮助企业实现数智化转型,消除信息孤岛,打造全程一体化的管理体系。魔方网表ERP拥有强大的表单功能和模块化的产品特点,使得企业可以根据自身业务需求,通过简单的拖拽和配置,快速搭建符合自身特点的…

linux使用docker实现redis主从复制和哨兵模式

目录 1. 拉取redis镜像 2.使用可视化redis工具 3. 设置从redis 4.设置哨兵模式 5. 使用docker-compose快速创建 1. 拉取redis镜像 docker pull redis 默认拉取最新的镜像。 然后pull结束后使用docker images检查镜像&#xff1a; 然后docker run创建container容器 首先…

测试需求分析

测试需求是什么&#xff1f; --需求文档 测试需求主要解决**“测什么”的问题&#xff0c;一般来自需求规格说明书中原始需求 测试需求应全部覆盖已定义的业务流程&#xff0c;以及功能和非功能**方面的需求 功能&#xff1a;基本用户需求–优先 非功能&#xff1a;界面&#…

使用DSP28335在CCS中生成正弦波

DSP芯片支持数学库&#xff0c;那如何通过DSP芯片生成一个正弦波呢&#xff1f;通过几天研究&#xff0c;现在将我的方法分享一下&#xff0c;如有错误&#xff0c;希望大家及时指出&#xff0c;共同进步。 sin函数的调用 首先看下一sin函数 的使用。 //头文件的定义 #includ…

基于springboot实现教学资源库系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现教学资源库系统演示 摘要 社会的进步&#xff0c;教育行业发展迅速&#xff0c;人们对教育越来越重视&#xff0c;在当今网络普及的情况下&#xff0c;教学模式也开始逐渐网络化&#xff0c;各大高校开始网络教学模式。 本文研究的教学资源库系统基于Sprin…

Linux的学习之路:8、Linux调试器-gdb使用

摘要 本章主要是说一下gdb的使用&#xff0c;以及把使用指令放入放个指令手册。 目录 摘要 一、背景 二、使用 1、产生debug文件 2、进入gdb 3、使用指令 三、思维导图 一、背景 Linux调试器gdb的背景主要涉及到Linux程序发布方式和调试需求。 在Linux中&#xff0c…

一款自研Python解释器

项目简介: PikaScript是一个完全重写的超轻量级python引擎,具有完整的解释器,字节码和虚拟机架构,可以在少于4KB的RAM下运行,用于小资源嵌入式系统。相比同类产品,如MicroPython,LuaOS等,资源占用减少85%以上。 入选2021年度 Gitee最有价值开源项目,加入RT-Thread嵌入…

动态规划(背包问题)

一:动态规划概述: 动态规划实际上是一种将原本的 大 方面的问题转化为许许多多的 小方面 的一种应用, 在一定程度上避免数据的重复, 并且能够将数据以自己希望的方式进行存储, 用来解决多阶段的数学问题, 从而提高算法的效率 在算法当中, 动态规划主要包括有: 递推, 线性DP 记忆…

不惑之年,反思我如何成为一个程序员

不惑之年&#xff0c;反思我如何成为一个程序员 文章目录 不惑之年&#xff0c;反思我如何成为一个程序员01/偶然掉入码河02/现实撕碎理想03/发展选择方向04/时代成就向往05/幸运装饰未来 在这个充满生机与希望的季节&#xff0c;博主有幸收到一家国企邀约面试&#xff0c;并顺…

【好消息】思维100活动历年真题模拟题700多道上线了,供反复吃透

今天是星期五&#xff0c;距离4月20日举办的上海小学生 2024年春季思维100活动线上比赛还有8天的时间&#xff0c;明天、后天的周末是可以用来备考的大块时间&#xff0c;报名了的同学要充分利用了。 为了帮助各位小朋友了解思维100活动的历年考试真题、官方发布的参考样题&…

ssm044基于java和mysql的多角色学生管理系统+jsp

学生管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本学生管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处…

力扣207.课程表

你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示如果要学习课程 ai 则 必须 先学习课程 bi 。 例如…

新版chrome 解决在http协议下无法调用摄像头和麦克风的问题(不安全)

解决办法&#xff1a;亲测可行 chrome浏览器地址栏中输入chrome://flags/#unsafely-treat-insecure-origin-as-secure&#xff0c;回车&#xff0c;如下图&#xff0c;将该选项置为Enabled&#xff0c; edge浏览器打开&#xff1a;edge://flags/#unsafely-treat-insecure-orig…

TDengine taosAdapter启用HTTPS

HTTPS &#xff08;Hypertext Transfer Protocol Secure &#xff09;&#xff0c;是以安全为目标的 HTTP 通道&#xff0c;在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。HTTPS 在HTTP 的基础下加入SSL&#xff0c;HTTPS 的安全基础是 SSL&#xff0c;因此加…

利用细粒度检索增强和自我检查提升对话式问题解答能力

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 论文标题&#xff1a;Boosting Conversational Question Answering with Fine-Grained Retrieval-Augmentation and Self-Check 论文地址&#xff1a;https://arxiv.org/abs/2403.18243 检索增强生成…