(二)结构型模式:7、享元模式(Flyweight Pattern)(C++实例)
目录
1、享元模式(Flyweight Pattern)含义
2、享元模式的UML图学习
3、享元模式的应用场景
4、享元模式的优缺点
5、C++实现享元模式的简单实例
1、享元模式(Flyweight Pattern)含义
享元模式(Flyweight),运用共享技术有效地支持大量细粒度地对象。
(1)享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来最大程度地减少内存使用和提高性能。它适用于存在大量细粒度对象且这些对象之间有许多共享状态的情况。
(2)在享元模式中,将对象分为两种状态:内部状态(Intrinsic State)和外部状态(Extrinsic State)。内部状态是对象固有的、不会随着外部环境变化而变化的状态,可以被多个对象共享;而外部状态是对象依赖的、可能随着外部环境变化而变化的状态,每个对象都需要单独维护。
(3)享元模式的核心思想是将可共享的内部状态从具体对象中提取出来,并将其存储在一个享元池(或缓存)中。当需要创建对象时,先检查享元池中是否已经存在相应的享元对象,如果存在则直接返回,如果不存在则创建新的享元对象并放入享元池中。客户端通过享元工厂来获取或操作享元对象,同时传递外部状态给享元对象进行处理。
2、享元模式的UML图学习

在享元模式中,主要包含以下几个角色:
(1)享元工厂(Flyweight Factory):负责创建和管理享元对象。它维护一个享元池(或缓存),用于存储已经创建的享元对象,并根据客户端的请求返回相应的享元对象。
(2)抽象享元(Flyweight):定义了享元对象的接口,声明了享元对象可以接收的外部状态参数。
(3)具体享元(Concrete Flyweight):实现了抽象享元接口,同时也包含内部状态。具体享元对象需要注意内部状态和外部状态的分离,确保内部状态是可共享的。
(4)UnshareConcreteFlyweight是指那些不需要共享地Flyweight子类。因为Flyweight接口共享成为可能,但它并不强制共享,解决那些不需要共享对象地问题。
(5)客户端(Client):通过享元工厂来获取或操作享元对象。客户端通常会维护一些外部状态,并将其传递给享元对象进行处理。
3、享元模式的应用场景
(1)系统中存在大量相似对象,且创建和销毁这些对象会消耗大量资源时,可以考虑使用享元模式来共享对象。
(2)对象的状态可以分为内部状态和外部状态,且内部状态相对稳定不变,而外部状态可变时,可以使用享元模式来共享内部状态,减少对象的数量。
4、享元模式的优缺点
(1)优点:
1)节省内存:通过共享对象,减少了系统中对象的数量,从而节省了内存空间。特别是当需要创建大量细粒度的对象时,享元模式可以显著减少内存的消耗。
2)提高性能:由于共享对象可以被多个客户端共享,因此可以减少对象的创建和销毁次数,提高了系统的性能。
3)支持可变状态和不可变状态:享元模式将对象的状态分为内部状态和外部状态,其中内部状态是不可变的,而外部状态是可变的。这样可以在一定程度上支持对象的可变性,同时保持了对象的共享性。
(2)缺点:
1)对象共享可能导致线程安全问题:如果多个线程同时访问并修改了共享对象的外部状态,就会出现线程安全问题。在使用享元模式时,需要注意对共享对象的并发访问进行合理的同步控制。
2)增加了系统的复杂性:引入享元模式会增加系统的复杂性,需要额外的工厂类来管理享元对象的创建和共享。这增加了代码的复杂性和维护成本。
总结: 享元模式通过共享对象来减少系统中对象的数量,从而节省了内存空间,并提高了系统的性能。然而,它也增加了系统的复杂性,并可能引入线程安全问题。在使用享元模式时,需要根据具体情况权衡利弊,合理设计和管理共享对象。
5、C++实现享元模式的简单实例
#include <iostream>
#include <unordered_map>// 抽象享元类
class Flyweight
{
public:virtual void operation(int extrinsicState) = 0;
};// 具体享元类
class ConcreteFlyweight : public Flyweight
{
public:void operation(int extrinsicState) override {std::cout << "具体享元对象,外部状态:" << extrinsicState << std::endl;}
};// 享元工厂类
class FlyweightFactory
{
private:std::unordered_map<int, Flyweight*> flyweights;public:Flyweight* getFlyweight(int key){if (flyweights.find(key) == flyweights.end()) {flyweights[key] = new ConcreteFlyweight();}return flyweights[key];}
};int main()
{FlyweightFactory factory;Flyweight* fw1 = factory.getFlyweight(1);fw1->operation(10);Flyweight* fw2 = factory.getFlyweight(2);fw2->operation(20);Flyweight* fw3 = factory.getFlyweight(1); // 从缓存中获取已有的享元对象fw3->operation(30);delete fw1;delete fw2;// 注意:不要删除fw3,因为它是从享元池中获取的对象,由享元工厂负责管理和销毁return 0;
}
在上述示例中,通过享元工厂(FlyweightFactory)创建和管理享元对象(ConcreteFlyweight)。客户端根据需要获取具体的享元对象,并传递外部状态给享元对象进行操作。
相关文章:
(二)结构型模式:7、享元模式(Flyweight Pattern)(C++实例)
目录 1、享元模式(Flyweight Pattern)含义 2、享元模式的UML图学习 3、享元模式的应用场景 4、享元模式的优缺点 5、C实现享元模式的简单实例 1、享元模式(Flyweight Pattern)含义 享元模式(Flyweight)…...
laravel 多次查询请求,下次请求清除上次请求的where 条件
在Laravel中,可以使用where方法来添加查询条件,但是每次添加where条件时,都会在查询构造器中持久化这些条件,直到你手动重置它们。所以,如果你想在下一次查询中清除上次查询的where条件,有以下几种选择&…...
C++根据如下使用类MyDate的程序,写出类MyDate的定义,MyDate中有三个数据成员:年year,月month,日day完成以下要求
题目: 根据如下使用类MyDate的程序,写出类MyDate的定义,MyDate中有三个数据成员: 年year,月month,日day int year,month,day; void main() { MyDate d1, d2; d1.set(2015, 12, 31); d2.set(d1); d1.…...
微盟集团中报增长稳健 重点发力智慧零售AI赛道
零售数字化进程已从渠道构建走向了用户的深度运营。粗放式用户运营体系无法适应“基于用户增长所需配套的精细化运营能力”,所以需要有个体、群体、个性化、自动化运营——即在对的时候、以对的方式、把对的内容推给用户。 出品|产业家 2023年已经过半,经济复苏成为…...
设计模式(7)模板方法模式
一、定义: 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。 //模板方法抽象类 public abstract class AbstractClass {//模板方法publ…...
2308C++协程流程9
参考 #include <协程> #include "简异中.cpp" //用来中文定义的.元<类 T>构 P;元<类 T>构 任务{用 承诺型P<T>;任务()默认;动 符号 协待()常 无异{构 等待器{极 直接协()常 无异{中 p.是准备好();}协柄 挂起协(协柄<>o)常 无异{p.连续…...
基于学习交流社区的自动化测试实现
一 项目介绍 项目名称 项目名称: 学习交流社区 项目介绍 项目介绍: 学习交流社区是一个基于Spring的前后端分离的在线论坛系统。使用了MySQL数据库来存储相关信息,项目完成后使用Xshell将其部署到云服务器上。 前端页面: 前端共由…...
2023-08-21力扣每日一题
链接: 2337. 移动片段得到字符串 题意: L可以和左边的_交换,R可以和右边的_交换,求判断A是否能通过交换(不限次数)变成B 解: 观察可知,如果存在RL,一定不能交换出LR,…...
对象存储服务-MinIO基本集成
是什么 MinIO 是一个高性能的分布式对象存储服务,适合存储非结构化数据,如图片,音频,视频,日志等。对象文件最大可以达到5TB。 安装启动 mkdir -p /usr/local/minio cd /usr/local/minio# 下载安装包 wget https:/…...
Yarn介绍及快速安装 - Debian/Ubuntu Linux
1.Yarn介绍 Yarn 是一个用于管理 JavaScript 包的快速、可靠和安全的包管理器。它是由 Facebook、Google、Exponent 和 Tilde 团队共同开发的,旨在提供比 npm 更快速、可靠的包管理体验。 以下是 Yarn 的一些主要特点和优势: 快速安装:Yarn…...
【新日语(2)】第10課 中国の生活に慣れるかどうか少し心配です
第10課 中国の生活に慣れるかどうか少し心配です 注释: ~かどうか:“是否”。 练习A 一、例句 田中さんは鈴木さんに、30分ぐらい遅れると言いました。 田中先生告诉铃木先生,他会迟到大约30分钟。 注释: &…...
Python 网页解析初级篇:BeautifulSoup库的入门使用
在Python的网络爬虫中,网页解析是一项重要的技术。而在众多的网页解析库中,BeautifulSoup库凭借其简单易用而广受欢迎。在本篇文章中,我们将学习BeautifulSoup库的基本用法。 一、BeautifulSoup的安装与基本使用 首先,我们需要使…...
Spring Schedular 定时任务
大家好 , 我是苏麟 , 今天带来定时任务的实现 . Spring网站 : 入门 |计划任务 (spring.io) 什么是定时任务 通过时间表达式来进行调度和执行的一类任务被称为定时任务 定时任务实现 1.Spring Schedule (Spring boot 默认整合了) 2.Quartz(独立于Spring 存在的定时任务框架…...
营业额统计
营业额统计 # 题目描述 Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日&…...
使用lodash的throttle函数会触发两次
当使用lodash的throttle函数时会触发两次,分别在最开始和最后。 严格来说不算是bug,因为官方文档写的很清楚。throttle函数其实有三个参数: _.throttle(func, [wait0], [options]) func: 要节流的函数 wait: 等待时间 options: 选项 op…...
如何使用CSS实现一个瀑布流布局?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现瀑布流布局⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚…...
dfs之有重复字符串的排列组合
https://leetcode.cn/problems/permutation-ii-lcci/description/ ■ 题目描述 考古问题,假设以前的石碑被打碎成了很多块,每块上面都有一个或若干个字符,请你写个程序来把之前石碑上文字可能的组合全部写出来,按升序进行排列。…...
Java之抽象类
Java之抽象类 抽象类概念抽象类如何使用抽象类的特性 作者简介: zoro-1,目前大一,正在学习Java,数据结构等 作者主页:zoro-1的主页 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖Ὁ…...
“无Internet连接但是可以上网” 解决全流程
先说我的最后解决方法: 修改注册表下\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet下 的 EnableActiveProbing 项:将 1 改成 0 为什么要解决“无Internet连接但是可以上网”这个问题? 因为虽然可以上百…...
VS2022 CMake报错解决小结
目录 一、问题背景 二、问题分析 三、问题解决 一、问题背景 VS2022中能够跨平台的工程类型就是CMake项目,一套代码能跨windows/Linux/Mac多种操作系统。而实际使用时,发现相关资料比较少,需要摸索一下。 碰到的问题简述: 1、C…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
