《设计模式的艺术》笔记 - 享元模式
介绍
享元模式运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,是一种对象结构型模式。
实现
myclass.h
//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>
#include <unordered_map>class Flyweight { // 享元抽象类
public:Flyweight(const std::string &in);virtual void operation(const std::string &out) = 0;const std::string &getMIn() const;private:std::string m_in;
};class ConcreteFlyweight : public Flyweight { // 具体享元类
public:ConcreteFlyweight(const std::string &in);void operation(const std::string &out) override;
};class FlyweightFactory { // 配合工厂模式使用享元工厂类
public:~FlyweightFactory();Flyweight *getFlyweight(const std::string &key);
private:std::unordered_map<std::string, Flyweight *> m_flyweights;
};#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"Flyweight::Flyweight(const std::string &in) {m_in = in;
}const std::string &Flyweight::getMIn() const {return m_in;
}ConcreteFlyweight::ConcreteFlyweight(const std::string &in) : Flyweight(in) {}void ConcreteFlyweight::operation(const std::string &out) {std::cout<< "内部状态: " << getMIn() << ", 外部状态: " << out << std::endl;
}FlyweightFactory::~FlyweightFactory() {for (auto it : m_flyweights) {if (it.second) {delete it.second;}}
}Flyweight* FlyweightFactory::getFlyweight(const std::string &key) {auto it = m_flyweights.find(key);if (it != m_flyweights.end()) {return it->second;} else {Flyweight *flyweight = new ConcreteFlyweight(key);m_flyweights.insert(std::make_pair(key, flyweight));return flyweight;}
}
main.cpp
#include <iostream>
#include <mutex>
#include "myclass.h"int main() {FlyweightFactory *factory = new FlyweightFactory();auto fly1 = factory->getFlyweight("a");auto fly2 = factory->getFlyweight("b");auto fly3 = factory->getFlyweight("a");fly1->operation("1");fly2->operation("2");fly3->operation("3");delete factory;return 0;
}
总结
优点
1. 可以极大减少内存中对象的数量,使得相同或相似对象在内存中只保存一份,从而可以节约系统资源,提高系统性能。
2. 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。
缺点
1. 享元模式需要分离出内部状态和外部状态,从而使得系统变得复杂,这使得程序的逻辑复杂化。
2. 为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长。
适用场景
1. 一个系统有大量相同或者相似的对象,造成内存的大量耗费。
2. 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
3. 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源。因此,在需要多次重复使用同一享元对象时才值得使用享元模式。
练习
myclass.h
//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>
#include <unordered_map>class Flyweight { // 享元抽象类
public:Flyweight(const std::string &in);virtual void display(const std::string &out) = 0;const std::string &getMIn() const;private:std::string m_in;
};class PictureFlyweight : public Flyweight { // 具体享元类
public:PictureFlyweight(const std::string &in);void display(const std::string &out) override;
};class AnimationFlyweight : public Flyweight { // 具体享元类
public:AnimationFlyweight(const std::string &in);void display(const std::string &out) override;
};class VideoFlyweight : public Flyweight { // 具体享元类
public:VideoFlyweight(const std::string &in);void display(const std::string &out) override;
};class FlyweightFactory { // 配合工厂模式使用享元工厂类
public:~FlyweightFactory();Flyweight *getFlyweight(const std::string &key);static FlyweightFactory *getInstance();
private:FlyweightFactory();std::unordered_map<std::string, Flyweight *> m_flyweights;
};#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"Flyweight::Flyweight(const std::string &in) {m_in = in;
}const std::string &Flyweight::getMIn() const {return m_in;
}PictureFlyweight::PictureFlyweight(const std::string &in) : Flyweight(in) {}void PictureFlyweight::display(const std::string &out) {std::cout << out << ", " << getMIn() << std::endl;
}AnimationFlyweight::AnimationFlyweight(const std::string &in) : Flyweight(in) {}void AnimationFlyweight::display(const std::string &out) {std::cout << out << ", " << getMIn() << std::endl;
}VideoFlyweight::VideoFlyweight(const std::string &in) : Flyweight(in) {}void VideoFlyweight::display(const std::string &out) {std::cout << out << ", " << getMIn() << std::endl;
}FlyweightFactory::FlyweightFactory() {}FlyweightFactory* FlyweightFactory::getInstance() {static FlyweightFactory *factory = new FlyweightFactory();return factory;
}FlyweightFactory::~FlyweightFactory() {for (auto it : m_flyweights) {if (it.second) {delete it.second;}}
}Flyweight* FlyweightFactory::getFlyweight(const std::string &key) {auto it = m_flyweights.find(key);if (it != m_flyweights.end()) {return it->second;} else {Flyweight *flyweight = nullptr;if (key == "图片") {flyweight = new PictureFlyweight(key);} else if (key == "动画") {flyweight = new AnimationFlyweight(key);} else if (key == "视频") {flyweight = new VideoFlyweight(key);}m_flyweights.insert(std::make_pair(key, flyweight));return flyweight;}
}
main.cpp
#include <iostream>
#include <mutex>
#include "myclass.h"int main() {FlyweightFactory *factory = FlyweightFactory::getInstance();factory->getFlyweight("图片")->display("1");factory->getFlyweight("动画")->display("2");factory->getFlyweight("视频")->display("3");factory->getFlyweight("图片")->display("4");return 0;
}
相关文章:
《设计模式的艺术》笔记 - 享元模式
介绍 享元模式运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式ÿ…...
ubuntu系统(10):使用samba共享linux主机中文件
目录 一、samba安装步骤 1、Linux主机端操作 (1)安装sabma (2)修改samba配置文件 (3)为user_name用户设置samba访问的密码 (4)重启samba服务 2、Windows端 二、使用 1、代码…...
数据集成时表模型同步方法解析
01 背景介绍 数据治理的第一步,也是数据中台的一个基础功能 — 即将来自各类业务数据源的数据,同步集成至中台 ODS 层。业务数据源多种多样,单单可能涉及到的主流关系型数据库就有近十种。功能更加全面的数据中台通常还具有对接非关系型数据…...
彻底解决charles抓包https乱码的问题
最近做js逆向,听说charles比浏览器抓包更好用,结果发现全是乱码,根本没法用。 然后查询网上水文:全部都是装证书,根本没用! 最后终于找到解决办法,在这里记录一下: 乱码的根本原因…...
Towards Robust Blind Face Restoration with Codebook Lookup Transformer
Towards Real World Blind Face Restoration with Generative Facial Prior 这个projec相对codeformer已经是老一些的了,CodeFormer paper说自己的效果比这个更好。 有看了这个视频,它借用了R-ESRGAN 4x 和 GFPGAN 50%,既保留了一些人物特征…...
flutter3使用dio库发送FormData数据格式时候的坑,和get库冲突解决办法
问题描述 问题1:当你使用FormData.from(Flutter3直接不能用)的时候,可能会提示没有这个方法,或者使用FormData.fromMap(flutter3的dio支持)的时候也提示没有,这时候可能就是和get库里面的Formdata冲突了 问题1:The me…...
matlab读取pwm波数据,不用timer的方法,这里可以参考。Matlab/Simulink之STM32开发-编码器测速
这里提供了一个不用timer的方法,可以参考: https://blog.csdn.net/weixin_36967309/article/details/88699830 Matlab/Simulink之STM32开发-编码器测速...
使用 Python 创造你自己的计算机游戏(游戏编程快速上手)第四版:第十九章到第二十一章
十九、碰撞检测 原文:inventwithpython.com/invent4thed/chapter19.html 译者:飞龙 协议:CC BY-NC-SA 4.0 碰撞检测涉及确定屏幕上的两个物体何时相互接触(即发生碰撞)。碰撞检测对于游戏非常有用。例如,如…...
Multimodal Multitask Learning with a Unified Transformer
SNLI-VE dataset,natural language understanding tasks:MNLI,QNLI,QQP,SST-2 截止到发文时间的issue数,多吓人呐,不建议复现...
c指针和字符数组初学者比较好的例子
本练习的主题:一个对象的指针可以修改这个对象的内容; 注:对象是指一个固定大小的内存块。 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> int getMem(char **p1,int *m…...
微信原生小程序上传与识别以及监听多个checkbox事件打开pdf
1.点击上传并识别 组件样式<van-field border"{{ false }}" placeholder"请输入银行卡卡号" model:value"{{bankNo}}" label"卡号"><van-icon bindtap"handleChooseImg" slot"right-icon" name"sca…...
关于C#中Monitor的wait/pulse的理解
wait:表示释放对象上的锁并阻止当前线程,直到它重新获取该锁。 pulse:表示通知等待队列中的线程锁定对象状态的更改。 当线程调用 Wait 时,它会释放对象上的锁并进入对象的等待队列。 对象的就绪队列中的下一个线程 (如果有一个…...
LeetCode 2894. 分类求和并作差
给你两个正整数 n 和 m 。 现定义两个整数 num1 和 num2 ,如下所示: num1:范围 [1, n] 内所有 无法被 m 整除 的整数之和。 num2:范围 [1, n] 内所有 能够被 m 整除 的整数之和。 返回整数 num1 - num2 。 示例 1: …...
PLSQL 把多个字段转为json格式
PLSQL 把多个字段转为json格式 sql Select cc.bm, cc.xm, json_arrayagg(cc.hb) jgFrom (Select aa.bm, aa.xm, json_object(aa.ksbh, aa.wjmc) hbFrom (Select 001 bm, 老六 xm, 0001 ksbh, 文具盒 wjmcFrom dual tUnion AllSelect 001 bm, 老六 xm, 0002 ksbh, 毛笔 wjmcFr…...
国内环境 GitHub 拉取仓库速度慢的缓解方案
第一步: 浏览器打开如下两个网址,找到对应 IP 地址: GitHub.com - GitHub: Lets build from here GitHubgithub.global.ssl.fastly.net 假设对应 IP 地址分别为 140.82.xx.xxx 和 199.232.yy.yyy 第二步: 编辑 hosts 文件 sud…...
设计模式⑥ :访问数据结构
文章目录 一、前言二、Visitor 模式1. 介绍2. 应用3. 总结 三、Chain of Responsibility 模式1. 介绍2. 应用3. 总结 参考内容 一、前言 有时候不想动脑子,就懒得看源码又不像浪费时间所以会看看书,但是又记不住,所以决定开始写"抄书&q…...
无法打开浏览器开发者工具的可能解决方法
网页地址: https://jx.xyflv.cc/?url视频地址url 我在抖音里面抓了一个视频地址, 获取到响应的json数据, 找到里面的视频地址信息 这个网站很好用: https://www.jsont.run/ 可以使用js语法对json对象操作, 找到所有视频的url地址 打开网页: https://jx.xyflv.cc/?urlhttps:…...
Android ANR 总结
工作之余,对之前学习到的和结合自己项目过程中的遇到的问题经验做一些总结,下面讲一讲Android开发过程中遇到的ANR的问题,做一下整理 一、概述 解决ANR一直是Android 开发者需要掌握的重要技巧,一般从三个方面着手。 开发阶段&a…...
群晖Drive搭建云同步服务器结合内网穿透实现Obsidian笔记文件远程多端同步
文章目录 一、简介软件特色演示: 二、使用免费群晖虚拟机搭建群晖Synology Drive服务,实现局域网同步1 安装并设置Synology Drive套件2 局域网内同步文件测试 三、内网穿透群晖Synology Drive,实现异地多端同步Windows 安装 Cpolar步骤&#…...
Flutter中的图片查看器:使用photo_view库
在移动应用开发中,图片查看器是一个常见的需求。Flutter提供了许多库来简化这一过程,其中photo_view库是一个强大而灵活的选择。本文将介绍photo_view库的基本概念以及如何在Flutter应用中使用它来实现漂亮的图片查看体验。 1. 什么是photo_view库&…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
