当前位置: 首页 > news >正文

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 keystd::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采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象的状态处理(即只读不修改,否则后续可能无法重复使用)
  • 对象的数量太大从而导致对象内存开销加大——什么样的数量才算大?这需要仔细的根据具体应用情况进行评估,而不能凭空臆断。
    在这里插入图片描述
http://www.lryc.cn/news/337276.html

相关文章:

  • 【三十六】【算法分析与设计】综合练习(3),39. 组合总和,784. 字母大小写全排列,526. 优美的排列
  • ARM Cordio WSF(一)——架构简介
  • 设计模式总结-装饰者模式
  • Stunnel网络加密服务
  • 算法练习第16天|101. 对称二叉树
  • YOLOV8实战教程——最新安装(截至24.4)
  • redis zremove删除不掉【bug】
  • 对象的本地保存
  • PostgreSQL入门到实战-第二十一弹
  • 李彦宏放话:百度AI大模型绝不抢开发者饭碗
  • es 倒排索引
  • 阿里云服务器公网带宽费用全解析(不同计费模式)
  • python-pytorch实现lstm模型预测文本输出0.1.00
  • 77、WAF攻防——权限控制代码免杀异或运算变量覆盖混淆加密传参
  • A12 STM32_HAL库函数 之 HAL-ETH通用驱动 -- A -- 所有函数的介绍及使用
  • Linux从入门到精通 --- 1.初始Linux
  • linux使用docker实现redis主从复制和哨兵模式
  • 新版chrome 解决在http协议下无法调用摄像头和麦克风的问题(不安全)
  • 机器学习入门项目二(逻辑回归)
  • C++类引用的好处
  • 从零自制docker-9-【管道实现run进程和init进程传参】
  • 全量知识系统 程序详细设计 之 三种“活物” 之1(QA百度搜索 )
  • QT 线程之movetothread
  • 如何处理ubuntu22.04LTS安装过程中出现“Daemons using outdated libraries”提示
  • 跟TED演讲学英文:The inside story of ChatGPT‘s astonishing potential by Greg Brockman
  • mybatis05:复杂查询:(多对一,一对多)
  • 微电网优化:基于肝癌算法(Liver Cancer algorithm, LCA)的微电网优化(提供MATLAB代码)
  • VUE_H5页面跳转第三方地图导航,兼容微信浏览器
  • 智慧安全运营:智能化运维,确保服务无忧
  • R-tree总结