二十三种设计模式-享元模式

享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享相同对象来减少内存使用,尤其适合在大量重复对象的情况下。

核心概念

享元模式的核心思想是将对象的**可共享部分(内部状态)提取出来进行共享,而将不可共享部分(外部状态)**通过参数传递。这种方式可以显著减少内存占用,提高性能。

角色组成
  1. 抽象享元(Flyweight)
    定义了享元对象的接口,包含内部状态和外部状态的管理方法。

  2. 具体享元(Concrete Flyweight)
    实现了抽象享元接口,存储和管理内部状态。

  3. 享元工厂(Flyweight Factory)
    负责创建和管理享元对象,确保相同内部状态的对象只被创建一次。

  4. 非共享享元(Unshared Concrete Flyweight)
    不共享的部分,存储每个对象独立的状态。

应用场景

享元模式适用于以下场景:

  1. 大量相似对象的创建:当系统中存在大量相似对象,且这些对象占用大量内存时。

  2. 对象的共享性较强:对象的某些部分可以共享(如颜色、字体),而某些部分是特有的(如位置、大小)。

  3. 缓存场景:如数据库连接池、线程池等,通过共享技术减少内存占用。

优点

  1. 节省内存:通过共享对象,减少了内存中对象的数量。

  2. 提高性能:减少了对象创建和销毁的开销。

  3. 易于扩展:新的享元对象可以方便地加入系统。

缺点

  1. 实现复杂:需要维护共享对象的管理机制,增加了系统的复杂性。

  2. 线程安全问题:在多线程环境下,需要确保共享对象的线程安全。

实现示例

以下是一个简单的Java实现示例:

// 抽象享元类
interface Flyweight {void operation(String extrinsicState);
}// 具体享元类
class ConcreteFlyweight implements Flyweight {private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}@Overridepublic void operation(String extrinsicState) {System.out.println("Intrinsic State: " + intrinsicState + ", Extrinsic State: " + extrinsicState);}
}// 享元工厂类
class FlyweightFactory {private Map<String, Flyweight> flyweights = new HashMap<>();public Flyweight getFlyweight(String intrinsicState) {if (!flyweights.containsKey(intrinsicState)) {flyweights.put(intrinsicState, new ConcreteFlyweight(intrinsicState));}return flyweights.get(intrinsicState);}
}// 客户端代码
public class Client {public static void main(String[] args) {FlyweightFactory factory = new FlyweightFactory();Flyweight flyweight1 = factory.getFlyweight("A");Flyweight flyweight2 = factory.getFlyweight("B");Flyweight flyweight3 = factory.getFlyweight("A");flyweight1.operation("ClientState1");flyweight2.operation("ClientState2");flyweight3.operation("ClientState3");}
}

运行结果:

Intrinsic State: A, Extrinsic State: ClientState1
Intrinsic State: B, Extrinsic State: ClientState2
Intrinsic State: A, Extrinsic State: ClientState3

从输出可以看出,享元模式成功地实现了对相同对象的复用。

注意事项

  1. 合理划分内部状态和外部状态:内部状态存储在对象内部,外部状态通过参数传递。

  2. 享元对象的不可变性:享元对象应为不可变对象,避免线程安全问题。

  3. 权衡利弊:享元模式虽然可以节省内存,但会增加系统的复杂性。需要根据具体场景权衡是否使用。

享元模式在实际项目中广泛应用于需要优化内存使用和提高性能的场景,如缓存系统、图形界面、文本编辑器等。

享元模式(Flyweight Pattern)适用于以下具体场景:

1. 大量相似对象的场景

当系统中存在大量相似对象时,可以使用享元模式来减少内存占用。例如:

  • 文本编辑器中的字符对象:文本编辑器中大量重复出现的字符对象可以使用享元模式来共享。每个字符对象的字体、大小等内部状态可以共享,而位置、颜色等外部状态则由客户端管理。

  • 围棋棋子:在围棋程序中,黑色和白色棋子可以共享,而棋子的位置则作为外部状态。

  • 象棋棋子:象棋程序中,棋子的颜色(黑色或白色)可以共享,而棋子的位置则作为外部状态。

2. 缓存场景

享元模式可以用于实现缓存,特别是在需要频繁访问、计算成本高昂的数据时。通过共享已计算好的数据,可以提高系统的性能。

3. 数据库连接池和线程池

在数据库连接池和线程池中,享元模式可以用于共享可用的连接或线程对象,避免频繁地创建和销毁,从而提高系统性能。

4. 图形处理和游戏开发

  • 图形对象共享:在图形处理中,例如绘制大量相似的圆形、矩形等图形对象时,可以通过享元模式共享图形的内部状态(如颜色、大小等),而将位置等外部状态传递给具体对象。

  • 在线游戏中的角色属性:游戏中大量玩家角色的不变属性(如名称、等级、经验值等)可以共享,而装备、技能等级等可变属性则单独存储。

5. 大数据处理

在处理大量数据时,可能会存在大量的重复对象,如图像处理中的像素点、文本处理中的单词等。通过享元模式可以减少内存消耗和提高处理速度。

6. 性能和内存瓶颈问题

当应用程序遇到性能瓶颈,尤其是在内存使用上,享元模式可以通过复用对象来减轻内存压力。

7. 字符串常量池

Java中的字符串常量池是享元模式的一个经典应用。字符串常量池通过共享相同的字符串对象,减少了内存占用。

总结

享元模式适用于需要优化内存使用和提高性能的场景,特别是在系统中存在大量相似对象、对象创建和销毁成本较高、以及需要频繁访问和共享数据的情况下。然而,享元模式也会增加系统的复杂性,需要合理权衡其优缺点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/7870.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

routeros7 adguardhome添加规则报错certificate expired

mikrokit routeros 7添加adguardhome容器。 /container/add remote-imageadguard/adguardhome:latest interfaceveth1 root-dircontainer/adgurdhome loggingyes结果发现添加不了规则&#xff0c;报证书过期。 Error: control/filtering/add_url | Couldn’t fetch filter fro…

壁纸设计过程中如何增加氛围感

在壁纸设计过程中&#xff0c;增加氛围感是提升整体视觉效果和情感传达的关键。以下是一些具体的方法和技巧&#xff0c;帮助你在设计中营造出强烈的氛围感&#xff1a; 一、色彩运用 选择主题色&#xff1a; 根据你想要传达的情感选择主色调。例如&#xff0c;温暖的色调&…

RabbitMQ模块新增消息转换器

文章目录 1.目录结构2.代码1.pom.xml 排除logging2.RabbitMQConfig.java3.RabbitMQAutoConfiguration.java 1.目录结构 2.代码 1.pom.xml 排除logging <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/PO…

2024年度总结:技术探索与个人成长的交织

文章目录 前言年度创作回顾&#xff1a;技术深耕与分享数据库技术&#xff1a;MySQL 与 MyBatisJava 及相关技术栈计算机网络&#xff1a;构建网络知识体系思维方式的转变&#xff1a;构建技术知识体系的桥梁 项目实践&#xff1a;人工智能与智慧医疗的碰撞生活与博客的融合与平…

python:taichi 模拟一维波场

在 Taichi 中模拟一维波场&#xff0c;通常是利用 Taichi 编程语言的特性来对一维空间中的波动现象进行数值模拟&#xff0c;以下是相关介绍&#xff1a; 原理基础 波动方程&#xff1a;一维波动方程的一般形式为 &#xff0c;其中 u(x,t) 表示在位置x 和时间t 处的波的状态&…

基于回归分析法的光伏发电系统最大功率计算simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于回归分析法的光伏发电系统最大功率计算simulink建模与仿真。选择回归法进行最大功率点的追踪&#xff0c;使用光强和温度作为影响因素&#xff0c;电压作为输出进行建模。…

深入MapReduce——引入

引入 前面我们已经深入了HDFS的设计与实现&#xff0c;对于分布式系统也有了不错的理解。 但HDFS仅仅解决了海量数据存储和读写的问题。要想让数据产生价值&#xff0c;一定是需要从数据中挖掘出价值才行&#xff0c;这就需要我们拥有海量数据的计算处理能力。 下面我们还是…

Vue 引入及简单示例

Vue 渐进式JavaScript 框架 学习笔记 - Vue 引入及简单示例 目录 与jquery区别 Vue引入 两种方式引入 下载到本地 代码结构 简单示例 Style中引入vue.js 对vue语法进行解析 对三目运算符支持 设置变量&#xff08;状态&#xff09; 总结 与jquery区别 不需要手动操…

系统思考—问题分析

很多中小企业都在面对转型的难题&#xff1a;市场变化快&#xff0c;资源有限&#xff0c;团队协作不畅……这些问题似乎总是困扰着我们。就像最近和一位企业主交流时&#xff0c;他提到&#xff1a;“我们团队每天都很忙&#xff0c;但效率始终没见提升&#xff0c;感觉像是在…

π0:仅有3B数据模型打通Franka等7种机器人形态适配,实现0样本的完全由模型自主控制方法

Chelsea Finn引领的Physical Intelligence公司&#xff0c;专注于打造先进的机器人大模型&#xff0c;近日迎来了一个令人振奋的里程碑。在短短不到一年的时间内&#xff0c;该公司成功推出了他们的首个演示版本。这一成就不仅展示了团队的卓越技术实力&#xff0c;也预示着机器…

第二十一周:Mask R-CNN

Mask R-CNN 摘要Abstract文章信息研究动机Mask RCNNRoIPool与RoIAlign 双线性插值Mask Branch(FCN)其他细节Mask RCNN损失Mask分支预测 网络搭建创新点与不足总结 摘要 本篇博客介绍了Mask R-CNN&#xff0c;这是一种用于实例分割的模型&#xff0c;能够在目标检测的基础上实现…

Windows本地部署(DeepSeek-R1-Distill-Qwen-1.5B)模型

文章目录 Windows本地部署&#xff08;DeepSeek-R1-Distill-Qwen-1.5B&#xff09;模型本机环境运行环境安装安装 WSL2&#xff0c;启用linux 系统进入linux 系统后&#xff0c;安装以下软件安装 Anaconda3安装 CUDA安装 pip创建虚拟环境并安装 vllm 模型下载模型运行部署模型测…

Java 大视界 -- Java 大数据在元宇宙中的关键技术与应用场景(65)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

【QT】 控件 -- 显示类

&#x1f525; 目录 [TOC]( &#x1f525; 目录) 1. 前言 2. 显示类控件2.1 Label 1、显示不同文本2、显示图片3、文本对齐、自动换行、缩进、边距4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 &#x1f525; 1. 前言 之前我在上一篇文章【QT】…

大数据之路:阿里巴巴大数据实践(1)

第一章 总述 第二章 日志采集 2.1 浏览器的页面日志采集 览器的页面型产品/服务的日志采集可分为如下两大类 &#xff08;1&#xff09;页面浏览&#xff08;展现&#xff09;日志采集。顾名思义&#xff0c;页面浏览日志是指&#xff1a;一个页面被浏览器加载呈现时采集的日…

定时器按键tim_key模版

低优先级放在高优先级内势必是程序卡死 把高优先级放到低优先级内&#xff0c;会使程序卡死 可修改 Debuger调试方法 Pwm rcc #include "my_main.h" uint8_t led_sta0x10; char text[30]; void LED_Disp(uint8_t dsLED) {HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPI…

Linux的权限和一些shell原理

目录 shell的原理 Linux权限 sudo命令提权 权限 文件的属性 ⽂件类型&#xff1a; 基本权限&#xff1a; chmod改权限 umask chown 该拥有者 chgrp 改所属组 最后&#xff1a; 目录权限 粘滞位 shell的原理 我们广义上的Linux系统 Linux内核Linux外壳 Linux严格…

【ComfyUI专栏】ComfyUI 部署Kolors

什么是Kolors?我相信一定会有朋友可能第一次听说这个生图的模型,开始我也很难想象,这竟然是快手推出的可灵AI的项目,我们可以直接利用模型来生成图片和视频。 大家可以通过直接访问可灵AI的网址获取到可灵的项目,但是对于我们来说我们需要基于ComfyUI来生成必要的图片和视…

vue3+elementPlus之后台管理系统(从0到1)(day4-完结)

面包屑 创建一个面包屑组件 将路由导入然后格式化map对象 key-value 将当前路由的key和value获取然后存入list数组中 遍历list数据&#xff0c;渲染内容 <!--BreadcrumbCom.vue--> <template><el-breadcrumb separator">"><el-breadcrum…

非根目录部署 nextjs 项目,资源文件 请求404 的问题

最近在学习next项目编写的代码放到服务器上静态资源404 先分析问题 到服务器上查看是有资源目录的是不是项目配置有问题是不是nginx配置有问题 经过排查1和2是没有问题的目前来看只有3 检查一下nginx配置 尝试着把静态资源的配置禁用 问题解决 我的next项目用的是pm2管理…