【设计模式】享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享尽可能多的对象来有效支持大量细粒度的对象。这个模式主要用于减少内存使用和提高性能,特别是在需要创建大量相似对象的场景中。享元模式的核心思想是将对象的状态分为内在状态(Intrinsic State)和外在状态(Extrinsic State),其中内在状态存储在对象内部,并且对于所有引用该对象的地方都是相同的;而外在状态则由客户端管理并传递给对象。
享元模式的关键要素
-
Flyweight (享元)
这是一个接口或抽象类,声明了具体享元类应该实现的操作。
它定义了哪些方法可以访问内在状态,以及如何接收外在状态。
java
深色版本
public interface Flyweight {
void operation(int extrinsicState);
} -
ConcreteFlyweight (具体享元)
实现 Flyweight 接口的具体类。
包含内在状态,并且可能会根据传入的外在状态执行不同的操作。
java
深色版本
public class ConcreteFlyweight implements Flyweight {
private final String intrinsicState;public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}@Override
public void operation(int extrinsicState) {
System.out.println("Intrinsic State = " + this.intrinsicState);
System.out.println("Extrinsic State = " + extrinsicState);
}
} -
UnsharedConcreteFlyweight (非共享具体享元)
如果某些对象不能被共享,或者它们包含的全部是外在状态,则可以创建非共享的具体享元类。
这些对象不会被池化管理,而是直接由客户端创建和销毁。
java
深色版本
public class UnsharedConcreteFlyweight implements Flyweight {
@Override
public void operation(int extrinsicState) {
// 操作逻辑
}
} -
FlyweightFactory (享元工厂)
负责管理和创建享元对象。
它通常维护一个享元对象的缓存(如 HashMap),以确保相同内在状态的对象只创建一次,并能在后续请求时返回已存在的实例。
java
深色版本
import java.util.HashMap;
import java.util.Map;
public class FlyweightFactory {
private final Map<String, Flyweight> flyweights = new HashMap<>();
public Flyweight getFlyweight(String key) {return flyweights.computeIfAbsent(key, k -> new ConcreteFlyweight(k));
}
}
使用享元模式的好处
节省内存:通过共享不可变的部分,减少了内存占用。
提升性能:当需要频繁创建和销毁大量相似对象时,享元模式可以通过重用现有对象来加快程序运行速度。
简化对象管理:客户端只需要关心外在状态,而不需要处理每个对象的所有细节。
示例应用场景
文本编辑器中的字符格式:在一个大型文档中,如果每个字符都单独保存其字体、颜色等属性信息,将会消耗大量的内存。使用享元模式,可以将这些格式信息作为内在状态进行共享,而将字符位置等信息作为外在状态由客户端管理。
GUI 系统中的图标:对于 GUI 应用程序,可能有多个组件使用相同的图标。通过享元模式,可以确保每个唯一的图标只加载一次,并且可以在不同地方重复使用。
游戏开发中的敌人角色:在一些游戏中,同一类型的敌人角色可能具有相同的外观和行为。使用享元模式,可以将这些共同特征作为内在状态,而将位置、健康值等变化的数据作为外在状态。
注意事项
内外状态分离:正确区分内在状态和外在状态是成功应用享元模式的关键。内在状态应该是不可变的,而外在状态则是可变的并且由客户端提供。
线程安全问题:如果享元对象将在多线程环境中使用,必须确保内在状态的线程安全性。由于内在状态是不可变的,因此这通常不是问题,但仍然需要注意任何可能影响到对象共享的行为。
总之,享元模式适用于那些需要高效地管理大量相似对象的应用程序。通过合理利用对象共享机制,它可以显著降低系统资源消耗,同时保持良好的性能表现。
相关文章:
【设计模式】享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享尽可能多的对象来有效支持大量细粒度的对象。这个模式主要用于减少内存使用和提高性能,特别是在需要创建大量相似对象的场景中。享元模式的核心思想是将对象的状态分为…...
题目 1688: 数据结构-字符串插入
第一种方式字符串 #include<iostream> #include<cstring> #include<algorithm> using namespace std; int main(){string s1,s2;int n;cin>>s1>>s2>>n;s1.insert(n-1,s2);cout<<s1<<endl;return 0; } 第二种方式字符数组 …...
28.攻防世界PHP2
进入场景 扫描目录 [04:12:32] 403 - 303B - /.ht_wsr.txt [04:12:32] 403 - 306B - /.htaccess.bak1 [04:12:32] 403 - 308B - /.htaccess.sample [04:12:…...
QML QT6 WebEngineView 、Echarts使用和数据交互
QML 中的 WebEngineView 是用于显示网页内容的组件,它基于 Qt WebEngine,支持现代网页渲染和与 JavaScript 的交互。它通常用来在 QML 应用中嵌入浏览器或加载在线资源。WebEngineView 可以展示 HTML、CSS、JavaScript 等网页内容,并提供多种属性和方法来控制其行为。 如下…...
SpringBoot 整合 Mail 轻松实现邮件自动推送
简单使用 1、pom 包配置 pom 包里面添加 spring-boot-starter-mail 包引用 <dependencies><dependency> <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency> </de…...
MyBatis 核心知识与实践
一、MyBatis 概述 1. 框架简介 MyBatis 是一款支持自定义 SQL、存储过程以及高级映射的持久层框架。它避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的操作,使开发人员能够更专注于 SQL 语句的编写和业务逻辑的处理。 2. 核心组件 SqlSessionFactoryB…...
机器学习期末速成
文章目录 一、机器学习分类二、逻辑回归三、决策树四、集成学习算法五、支持向量机六、聚类七、特征工程和指标 文章参考自B站机器学习期末速成课 本文仅作者个人复习使用 一、机器学习分类 聚类和分类的区别: 分类:一开始就知道有哪些类别 聚类&#…...
Linux中的线程
目录 线程的概念 进程与线程的关系 线程创建 线程终止 线程等待 线程分离 原生线程库 线程局部存储 自己实现线程封装 线程的优缺点 多线程共享与独占资源 线程互斥 互斥锁 自己实现锁的封装 加锁实现互斥的原理 死锁 线程同步 线程的概念 回顾进程相关概念 …...
AI大模型学习笔记|多目标算法梳理、举例
多目标算法学习内容推荐: 1.通俗易懂讲算法-多目标优化-NSGA-II(附代码讲解)_哔哩哔哩_bilibili 2.多目标优化 (python pyomo pareto 最优)_哔哩哔哩_bilibili 学习笔记: 通过网盘分享的文件:多目标算法学习笔记 链接: https://pan.baidu.com…...
蓝桥杯刷题——day3
蓝桥杯刷题——day3 题目一题干题目解析代码 题目二题干题目解析代码 题目一 题干 每张票据有唯一的 ID 号,全年所有票据的 ID 号是连续的,但 ID 的开始数码是随机选定的。因为工作人员疏忽,在录入 ID 号的时候发生了一处错误,造…...
企业级日志分析系统ELK之ELK概述
ELK 概述 ELK 介绍 什么是 ELK 早期IT架构中的系统和应用的日志分散在不同的主机和文件,如果应用出现问题,开发和运维人员想排 查原因,就要先找到相应的主机上的日志文件再进行查找和分析,所以非常不方便,而且还涉及…...
【开源项目】经典开源项目数字孪生体育馆—开源工程及源码
飞渡科技数字孪生体育馆管理平台,融合物联网IOT、BIM数据模型、三维GIS等技术,实现体育馆的全方位监控和实时全局掌握,同时,通过集成设备设施管理、人员管理等子系统,减少信息孤岛,让场馆“可视、可控、可管…...
C++多线程实战:掌握图像处理高级技巧
文章结尾有最新热度的文章,感兴趣的可以去看看。 本文是经过严格查阅相关权威文献和资料,形成的专业的可靠的内容。全文数据都有据可依,可回溯。特别申明:数据和资料已获得授权。本文内容,不涉及任何偏颇观点,用中立态度客观事实描述事情本身 导读 在当今的计算世界中,…...
解决MAC装win系统投屏失败问题(AMD显卡)
一、问题描述 电脑接上HDMI线后,电脑上能显示有外部显示器接入,但是外接显示器无投屏画面 二、已测试的方法 1 更改电脑分辨,结果无效 2 删除BootCamp,结果无效 3更新电脑系统,结果无效 4 在设备管理器中&#…...
网易游戏分享游戏场景中MongoDB运行和分析实践
在游戏行业中,数据库的稳定和性能直接影响了游戏质量和用户满意度。在竞争激烈的游戏市场中,一个优秀的数据库产品无疑能为游戏的开发和后期的运营奠定良好的基础。伴随着MongoDB在不同类型游戏场景中的应用越来越广泛,许多知名的游戏公司都在…...
Android14 AOSP 允许system分区和vendor分区应用进行AIDL通信
在Android14上,出于种种原因,system分区的应用无法和vendor分区的应用直接通过AIDL的方法进行通信,但是项目的某个功能又需要如此。 好在Binder底层其实是支持的,只是在上层进行了屏蔽。 修改 frameworks/native/libs/binder/Bp…...
R学习——因子
目录 1 定义因子(factor函数) 2因子的作用 一个数据集中的 只需要考虑可以用哪个数据来进行分类就可以了,可以用来分类就可以作为因子。 Cy1这个因子对应的水平level是4 6 8: 1 定义因子(factor函数) 要…...
pytest入门三:setup、teardown
https://zhuanlan.zhihu.com/p/623447031 function对应类外的函数,每个函数调用一次 import pytest def setup_module():print(开始 module)def teardown_module():print(结束 module)def setup_function():print(开始 function)def teardown_function():print(结…...
前端面试准备问题2
1.防抖和节流分别是什么,应用场景 防抖:在事件被触发后,只有在指定的延迟时间内没有再次触发,才执行事件处理函数。 在我的理解中,简单的说就是在一个指定的时间内,仅触发一次,如果有多次重复触…...
web前端sse封装
这是一个基于microsoft/fetch-event-source包封装的sse函数,包含开始、停止功能; 可传更多参数、使用非常简单。 使用前: 安装 microsoft/fetch-event-source 代码: // sse import { fetchEventSource } from microsoft/fetch-event-source import { …...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...
