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

11 享元(Flyweight)模式

享元模式

1.1 分类

(对象)结构型

1.2 提出问题

做一个车管所系统,将会产生大量的车辆实体,如果每一个实例都保存自己的所有信息,将会需要大量内存,甚至导致程序崩溃。

1.3 解决方案

运用共享技术有效的支持大量细粒度的对象。

1.4 实现类图

在这里插入图片描述

  1. 享元模式只是一种优化。只有存在大量类似对象销毁内存的情况,才考虑使用。
  2. 享元(Flyweight)类包含原始对象中部分能在多个对象中共享的状态。享元中存储的状态被称为“内在状态”。传递给享元方法的状态被称为“外在状态”。
  3. 上下文(Context)类包含原始对象中各不相同的外在状态。上下文与享元对象组合在一起就能表示原始对象的全部状态。
  4. 通常情况下,原始对象的行为保留在享元类中。因此调用享元方法必须提供部分外在状态作为参数。但也可将行为移动到上下文类中,将连入的享元作为单纯的数据对象。
  5. 客户端(Client)负责计算或存储享元的外在状态。在客户端看来,享元是一种可在运行时进行配置的模板对象,具体的配置方式为向其方法中传入一些上下文数据参数。
  6. 享元工厂(Flyweight Factory)会对已有享元的缓存池进行管理。有了工厂后,客户端就无需直接创建享元,只需调用工厂并向其传递目标享元的一些内在状态即可。工厂会根据参数在之前已创建的享元中进行查找,如果找到满足条件的享元就将其返回;如果没有找到就根据参数新建享元。

1.5 示例代码

#include <iostream>
#include <string>
#include <unordered_map>using std::string;
//内部状态
struct SharedState {string m_brand;string m_model;string m_color;SharedState(const string& brand, const string model, const string color):m_brand(brand), m_model(model), m_color(color) {}friend std::ostream& operator<<(std::ostream& os, const SharedState& ss) {return os << "[" << ss.m_brand << "," << ss.m_model << "," << ss.m_color << "]";}
};
//外部状态
struct UniqueState
{std::string m_owner;std::string m_plates;UniqueState(const std::string& owner, const std::string& plates): m_owner(owner), m_plates(plates) {}friend std::ostream& operator<<(std::ostream& os, const UniqueState& us) {return os << "[ " << us.m_owner << " , " << us.m_plates << " ]";}
};//享元,存放共享状态,内部状态
class Flyweight {
private:SharedState m_sharedState;
public:Flyweight(const SharedState sharedState) : m_sharedState(sharedState) {}//使用的时候,使用外部状态作为参数,对整个context做出操作void operation(UniqueState uniqueState) const {std::cout << "Flyweight:显示内部状态("<< m_sharedState << "),显示外部状态:("<< uniqueState << ")\n";}
};
//享元工厂
class FlyweightFactory {
private:std::unordered_map<string, Flyweight> m_Flyweights;string getKey(const SharedState& ss) const {return ss.m_brand + "_" + ss.m_model + "_" + ss.m_color;}
public:FlyweightFactory(std::initializer_list<SharedState> share_states) {for (const SharedState& ss : share_states) {m_Flyweights.insert({ getKey(ss),Flyweight(ss) });}}Flyweight* getFlyWeight(const SharedState& shared_state) {string key = getKey(shared_state);if (m_Flyweights.find(key) == m_Flyweights.end()) {std::cout << "FlyweightFactory:没有找到需要的享元,创建一个新的。\n";m_Flyweights.insert({ key,shared_state });} else {std::cout << "FlyweightFactory:返回一个现有的享元。\n";}return &m_Flyweights.at(key);}void listFlyWeights() const {int count = m_Flyweights.size();std::cout << "\nFlyweightFactory:我有" << count << "个享元:\n";for (std::pair<std::string, Flyweight> item : m_Flyweights) {std::cout << item.first << "\n";}}
};
//上下文
class CarInfoContext {
private:Flyweight* m_flyWeight = nullptr;//内部状态UniqueState m_uniqueState;//外部状态
public:CarInfoContext(Flyweight* flyWeight, const UniqueState * unique_state) :m_flyWeight(flyWeight), m_uniqueState(*unique_state) {}void operation() {m_flyWeight->operation(m_uniqueState);}
};
//Client
class PoliceCarDatabase {
private:std::list<CarInfoContext*> carInfoDatabase;
public:~PoliceCarDatabase() {for (auto item : carInfoDatabase)delete item;}void addCarToPoliceDatabase(FlyweightFactory &ff,const string& owner, const string& plates,const string& brand, const string& model, const string& color) {std::cout << "\n客户端:添加车辆信息到数据库。\n";Flyweight* flyWeight = ff.getFlyWeight({ brand, model, color });//内部状态UniqueState uniqueState(owner, plates);//外部状态carInfoDatabase.push_back(new CarInfoContext(flyWeight, &uniqueState));std::cout << "\n客户端:数据库当前状态:\n";for (auto item : carInfoDatabase) {item->operation();}}
};
int main()
{FlyweightFactory factory({SharedState("奔驰","GLC","白色"),SharedState("奥迪","A7","黑色"),SharedState("宝马","X1","白色")});factory.listFlyWeights();PoliceCarDatabase database;database.addCarToPoliceDatabase(factory,"阿西拜", "赣ABC888", "奔驰", "GLC", "白色");factory.listFlyWeights();database.addCarToPoliceDatabase(factory,"阿西拜", "赣ABC999", "比亚迪", "唐EV", "蓝色");database.addCarToPoliceDatabase(factory,"阿西拜", "赣ABC666", "奔驰", "GLC", "白色");factory.listFlyWeights();
}

1.6 举个栗子

享元模式能有效减少在画布上渲染数百万个树状 对象时所需的内存。
在这里插入图片描述

1.7 总结

  1. 优点:如果程序中有很多相似对象,那么你将可以节省大量内存。
  2. 缺点:可能需要牺牲执行速度来换取内存,因为他人每次调用享元方法时都需要重新计算部分情景数据。

相关文章:

11 享元(Flyweight)模式

享元模式 1.1 分类 &#xff08;对象&#xff09;结构型 1.2 提出问题 做一个车管所系统&#xff0c;将会产生大量的车辆实体&#xff0c;如果每一个实例都保存自己的所有信息&#xff0c;将会需要大量内存&#xff0c;甚至导致程序崩溃。 1.3 解决方案 运用共享技术有效…...

PHP JSON操作指南

PHP JSON操作指南 概述 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。PHP作为一门流行的服务器端脚本语言&#xff0c;支持对JSON数据进行读取、编写和解析。本文将…...

【学习笔记】计算机图形学的几何数学基础知识

3D坐标系 左手系和右手系 点 x,y,z与w(齐次坐标) 矩阵 第一个下标表示行号,第二个下标表示列号。矩阵乘法不满足交换律矩阵乘法=矩阵合并一个矩阵乘以它的逆矩阵=单位矩阵变化矩阵 平移矩阵 缩放矩阵 除了可以缩放, 还可以利用缩放,在给定右手系的情况确定左手系…...

Python因为网络原因安装依赖库报错

现象 在终端运行以下指令 pip install pyautogui pillow keyboard 出现报错&#xff0c;终端信息如下&#xff1a; PS D:\code\Python> pip install pyautogui pillow keyboard Collecting pyautoguiUsing cached PyAutoGUI-0.9.54.tar.gz (61 kB)Installing build depe…...

什么是卸荷器?风力发电为什么要用卸荷器

目前市场上&#xff0c;那些功率低于400W的小型风力发电机&#xff0c;普遍缺乏刹车、稳速或限速机制。只要有足够的风力&#xff0c;发电机便会开始转动并产生电力。风力越强&#xff0c;转速就越快&#xff0c;这可能导致发电机因转速过高而损坏&#xff0c;甚至发生风机头飞…...

SQL Server详细使用教程(包含启动SQL server服务、建立数据库、建表的详细操作) 非常适合初学者

SQL Server详细使用教程(包含启动SQL server服务、建立数据库、建表的详细操作) 非常适合初学者 文章目录 目录 前言 一、启动SQL server服务的三种方法 1.不启动SQL server服务的影响 2.方法一&#xff1a;利用cmd启动SQL server服务 3.方法二&#xff1a;利用SQL Serv…...

大数据学习之Spark分布式计算框架RDD、内核进阶

一.RDD 28.RDD_为什么需要RDD 29.RDD_定义 30.RDD_五大特性总述 31.RDD_五大特性1 32.RDD_五大特性2 33.RDD_五大特性3 34.RDD_五大特性4 35.RDD_五大特性5 36.RDD_五大特性总结 37.RDD_创建概述 38.RDD_并行化创建 演示代码&#xff1a; // 获取当前 RDD 的分区数 Since ( …...

Unity 加载OSGB(webgl直接加载,无需转换格式!)

Unity webgl加载倾斜摄影数据 前言效果图后续不足 前言 Unity加载倾斜摄影数据&#xff0c;有很多的插件方便好用&#xff0c;但是发布到网页端均失败&#xff0c;因为webgl 的限制&#xff0c;IO读取失效。 前不久发现一个开源项目: UnityOSGB-main 通过两种方式在 Unity 中…...

tcp/ip网络协议,tcp/ip网络协议栈

TCP/IP网络协议和TCP/IP网络协议栈是互联网通信的基石&#xff0c;它们定义了电子设备如何连入因特网以及数据如何在它们之间传输的标准。以下是对TCP/IP网络协议和TCP/IP网络协议栈的详细解释&#xff1a; 一、TCP/IP网络协议 TCP/IP&#xff08;Transmission Control Proto…...

【Debug】the remote host closed the connection错误信息分析

出现的情况说明&#xff1a;QT软件。刚开始都可以连接成功 之后连接 断开几次 就会出现连接失败 错误信息是the remote host closed the connection。the remote host closed the connection广泛原因分析 这个错误通常意味着远端 STM32 服务器主动关闭了连接。可能的原因包括&a…...

SpringBoot扩展篇:@Scope和@Lazy源码解析

SpringBoot扩展篇&#xff1a;Scope和Lazy源码解析 1. 研究主题及Demo2. 注册BeanDefinition3. 初始化属性3.1 解决依赖注入3.2 创建代理 ContextAnnotationAutowireCandidateResolver#getLazyResolutionProxyIfNecessary3.3 代理拦截处理3.4 单例bean与原型bean创建的区别 4. …...

“AI隐患识别系统,安全多了道“智能护盾”

家人们&#xff0c;在生活和工作里&#xff0c;咱们都知道安全那可是头等大事。不管是走在马路上&#xff0c;还是在工厂车间忙碌&#xff0c;又或是住在高楼大厦里&#xff0c;身边都可能藏着一些安全隐患。以前&#xff0c;发现这些隐患大多靠咱们的眼睛和经验&#xff0c;可…...

通向AGI之路:人工通用智能的技术演进与人类未来

文章目录 引言:当机器开始思考一、AGI的本质定义与技术演进1.1 从专用到通用:智能形态的范式转移1.2 AGI发展路线图二、突破AGI的五大技术路径2.1 神经符号整合(Neuro-Symbolic AI)2.2 世界模型架构(World Models)2.3 具身认知理论(Embodied Cognition)三、AGI安全:价…...

论文阅读:InstanceDiffusion: Instance-level Control for Image Generation

CVPR2024文章 摘要&#xff1a; 文本到图像扩散模型产生高质量的图像&#xff0c;但不提供对图像中单个实例的控制。我们引入了InstanceDiffusion&#xff0c;它将精确的实例级控制添加到文本到图像扩散模型中。InstanceDiffusion 支持每个实例的自由形式的语言条件&#xff…...

7.攻防世界 wzsc_文件上传

打开题目页面如下 上传了一张带有木马的图片 返回的页面是空白的&#xff0c;不过路径变了 猜测存在根目录/upload 也可以通过dirsearch扫描根目录 命令&#xff1a; dirsearch -u http://61.147.171.105:65024/ -e* 终于得到了上传的文件的信息 但是测试发现.php文件以及.…...

以为是响应式对象丢失导致数据没有回显

背景&#xff1a;之前ruoyi生成的vue2代码&#xff0c; <el-form ref“form”&#xff0c;后面我改成vue3的写法&#xff0c;没有实例化form&#xff0c; 在vue3中是需要定义const form ref(); 导致点击了修改后&#xff0c;页面弹框显示出来&#xff0c;数据没有回显。 一直…...

来 Gitcode 免费体验 DeepSeek 蒸馏模型,开启 AI 探索新旅程

在 AI 技术飞速发展的时代&#xff0c;你是否也怀揣着对前沿科技的无限好奇与探索欲望&#xff1f;然而&#xff0c;昂贵的模型体验费用和复杂的操作流程&#xff0c;是不是让你一次次望而却步&#xff1f;现在&#xff0c;这些都不再是问题&#xff01;DeepSeek 蒸馏模型现已强…...

2.Mkdocs配置说明(mkdocs.yml)【最新版】

官方文件&#xff1a;Changing the colors - Material for MkDocs 建议详细学习一下上面的官方网站↑↑↑ 我把我目前的配置文件mkdocs.yml代码写在下面&#x1f447;&#x1f3fb; #[Info] site_name: Mkdocs教程 #your site name 显示在左上角 site_url: http://wcowin.wo…...

云轴科技ZStack+海光DCU:率先推出DeepSeek私有化部署方案

针对日益强劲的AI推理需求和企业级AI应用私有化部署场景&#xff08;Private AI&#xff09;&#xff0c;云轴科技ZStack联合海光信息&#xff0c;共同推动ZStack智塔全面支持DeepSeek V3/R1/Janus Pro系列模型&#xff0c;基于海光DCU实现高性能适配&#xff0c;为企业提供安全…...

扩增子分析|零模型2——基于βNTI的微生物随机性和确定性装配过程(箱线图和柱状图R中实现)

一、引言 我们之前发布的周集中老师团队零模型R中实战案例&#xff1a;扩增子分析|基于零模型的群落确定性和随机性构建过程——R实战_bmntd-CSDN博客。在文末只输出了一个.csv 表格。并没有提供绘图的方法&#xff0c;有小伙伴问如何在R中一键成图呢&#xff1f;还真可以&…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...