java设计模式:03-06-享元模式

享元模式(Flyweight Pattern)

享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享技术来有效地支持大量细粒度对象的重用。享元模式避免了在相似对象间的高开销,通过共享尽可能多的状态来尽量减少内存使用。享元模式的核心思想是将对象的状态分为内在状态(共享部分)和外在状态(不共享部分),内在状态可以被多个对象共享,而外在状态则需要在对象之间独立维护。

享元模式的应用场景

  • 系统中有大量相似对象,由于重复而造成了大量的内存开销。
  • 对象的状态可以分为内在状态和外在状态,其中内在状态可以共享。
  • 需要支持大量细粒度对象的共享,以减少内存开销,如文本编辑器中的字符对象、图形应用中的图形对象等。

享元模式的实现方式

1. 传统实现方式

思想:创建一个享元工厂,用于创建和管理享元对象。享元工厂确保共享享元对象的唯一实例,避免重复创建相同的对象。

实现方式

import java.util.HashMap;
import java.util.Map;// 享元接口
interface Flyweight {void operation(String extrinsicState);
}// 具体享元类
class ConcreteFlyweight implements Flyweight {private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}public 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 key) {if (!flyweights.containsKey(key)) {flyweights.put(key, new ConcreteFlyweight(key));}return flyweights.get(key);}
}// 客户端代码
public class FlyweightPattern {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("First Call");flyweight2.operation("Second Call");flyweight3.operation("Third Call");}
}

优点

  • 减少对象的创建,降低内存消耗。
  • 提高系统性能,通过共享技术避免对象的重复创建。
  • 提高了系统的可扩展性,可以很方便地新增具体享元类。

缺点

  • 增加系统的复杂性,需要维护一个享元对象的池。
  • 享元模式使得系统不容易理解和维护,因为它引入了众多的细粒度对象。
  • 可能不适用于内在状态无法分离的情况
2. 使用多线程和缓存优化的享元模式

思想:通过使用多线程和缓存技术来优化享元模式,确保享元工厂在高并发环境下的性能和正确性。

实现方式

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;// 享元接口
interface Flyweight {void operation(String extrinsicState);
}// 具体享元类
class ConcreteFlyweight implements Flyweight {private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}public void operation(String extrinsicState) {System.out.println("Intrinsic State = " + intrinsicState + ", Extrinsic State = " + extrinsicState);}
}// 享元工厂
class FlyweightFactory {private ConcurrentMap<String, Flyweight> flyweights = new ConcurrentHashMap<>();public Flyweight getFlyweight(String key) {flyweights.computeIfAbsent(key, k -> new ConcreteFlyweight(k));return flyweights.get(key);}
}// 客户端代码
public class OptimizedFlyweightPattern {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("First Call");flyweight2.operation("Second Call");flyweight3.operation("Third Call");}
}

优点

  • 线程安全:使用并发容器和原子操作,确保在高并发环境下的正确性。
  • 缓存优化:使用缓存技术减少对象的重复创建,提高性能。

缺点

  • 增加了代码复杂度:多线程和缓存技术的引入使得代码更加复杂。
  • 可能增加内存消耗:缓存技术可能会增加一定的内存开销。

总结

实现方式优点缺点
传统实现方式减少对象创建,降低内存消耗,提高系统性能,系统可扩展性高增加系统复杂性,需要维护享元对象池,不易理解和维护
使用多线程和缓存优化的享元模式线程安全,性能高,减少对象的重复创建代码复杂度增加,多线程和缓存技术的引入增加了系统复杂性

选择哪种实现方式应根据具体的需求和系统的复杂度来决定。如果系统中有大量的相似对象并且需要在高并发环境下使用,可以选择使用多线程和缓存优化的享元模式。如果系统的并发需求不高,可以选择传统实现方式。

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

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

相关文章

正则表达式:电子邮件地址的格式详解,及常见正则表达式符号的详细解释和匹配方式

一、第一部分是对该段电子邮件的详解 var Regex /^(?:\w\.?)*\w(?:\w\.)*\w$/; 1.^&#xff1a;这个符号表示匹配输入字符串的开始位置。 2.(?:...)&#xff1a;这是一个非捕获组&#xff08;non-capturing group&#xff09;&#xff0c;用于将正则表达式的一部分组合在…

B端产品经理能力培养(四)

B端产品经理能力模型 通用能力 学习能力 沟通能力 行业融入感主人翁精神 心态和情商 专业素养 责任心 自驱力、执行力 基础认知 产品行业认知&#xff1a;当前公司的产品所属细分领域、所处行业趋势、提供怎样的服务、产品和方案解决了客户哪些问题。 产品聚焦领域&a…

【Langchain大语言模型开发教程】模型、提示和解析

&#x1f517; LangChain for LLM Application Development - DeepLearning.AI 学习目标 1、使用Langchain实例化一个LLM的接口 2、 使用Langchain的模板功能&#xff0c;将需要改动的部分抽象成变量&#xff0c;在具体的情况下替换成需要的内容&#xff0c;来达到模板复用效…

【Linux服务器Java环境搭建】012在linux中安装消息队列RabbitMQ,以及对RabbitMQ设置、启动、开启可视化

系列文章目录 【Linux服务器Java环境搭建】 前言 上一篇博客竟然用了不到半小时就写完了&#xff0c;那就继续吧&#xff0c;如果对此系列感兴趣&#xff0c;可以点击系列【Linux服务器Java环境搭建】进行查看哈&#xff0c;这一篇主要是安装和配置消息队列RabbitMQ。 一、消…

[解决方法]git上传的项目markdown文件的图片无法显示

应该有不少初学者会遇到这种情况 以下是本人摸索出的解决方法 我使用的是typora&#xff0c;首先设置typora的图片设置 文件>偏好设置>图像 如下&#xff1a; 选择这个就会在此文件的同级目录下创建一个assets文件夹来存放此markdown文件的所有图片 然后勾选优先使用相…

monocle3拟时序分析怎么做到多样本间pseudotime值可比?

愿武艺晴小朋友一定得每天都开心 monocle3呢&#xff0c;有好多文章分享了它的流程。跟着学呢&#xff0c;也都能计算出一套pseudotime值。 在跑monocle3时&#xff0c;我就有一个困惑产生了&#xff1a;monocle3计算的pseudotime值在多样本间可比&#xff0c;该怎么做到呀&am…

在 ASP.NET Core Web API 中实现审计跟踪

一.介绍 审计跟踪对于跟踪数据变化、维护安全性规至关重要。在本文中&#xff0c;我们将在 ASP.NET Core Web API 中实现审计跟踪。该示例将涵盖从设置项目到执行 CRUD 操作和验证审计日志的所有内容。 二.先决条件 Visual Studio 或 Visual Studio CodeSQL Server&#xff…

学习大数据DAY20 Linux环境配置与Linux基本指令

目录 Linux 介绍 Linux 发行版 Linux 和 Windows 比较 Linux 就业方向&#xff1a; 下载 CentOS Linux 目录树 Linux 目录结构 作业 1 常用命令分类 文件目录类 作业 2 vim 编辑文件 作业 3 你问我第 19 天去哪了&#xff1f;第 19 天在汇报第一阶段的知识总结&#xff0c;没什…

QT5:多窗口跳转

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助 目录 前言 一、环境 二、步骤 三、代码实现 四、效果图 前言 学习使用qt5完成多窗口&#xff08;界面&#xff09;跳转&#xff1a;从主界面可分别跳转至界面一和界面二&#xf…

Spring Boot集成SFTP快速入门Demo

1.什么是SFTP&#xff1f; SFTP&#xff08;SSH File Transfer Protocol&#xff0c;也称 Secret File Transfer Protocol&#xff09;&#xff0c;是一种基于SSH&#xff08;安全外壳&#xff09;的安全的文件传输协议。使用SFTP协议可以在文件传输过程中提供一种安全的加密算…

主从复制 哨兵服务 数据类型 持久化

配置主从复制 一主多从结构 配置一主一从结构 修改配置文件 配置salve服务器 配置带验证的主从复制 查看密码&#xff0c;默认redis服务没有密码 192.168.88.61:6379> config get requirepass 设置密码 192.168.88.61:6379> config set requirepass 123456 输入密码…

Spring Boot2(Spring Boot 的Web开发 springMVC 请求处理 参数绑定 常用注解 数据传递)

目录 一、Spring Boot 的Web开发 1. 静态资源映射规则 2. enjoy模板引擎 二、springMVC 1. springMVC-请求处理 测试&#xff1a; 以post方式请求 限制请求携带的参数 GetMapping 查询 PostMapping 新增 DeleteMapping删除 PutMapping 修改 2. springMVC-参…

HarmonyOS鸿蒙- 跳转系统应用能力

一、通过弹窗点击设置跳转系统应用能力 1、 自定义弹窗效果图 2、 自定义弹窗代码 import { common, Want } from kit.AbilityKit; import { BusinessError } from kit.BasicServicesKit;export function alertDialog() {AlertDialog.show({title: ,message: 当前功能依赖定位…

ranger审计日志对接CDH solr

作者&#xff1a;耀灵 一、准备条件 1、已安装完毕ranger-admin 2、已在CDH上部署solr&#xff08;注意在安装solr时更改下solr在zk上的节点信息&#xff09; 二、更改相关配置 1、修改ranger-2.1.0-admin/contrib/solr_for_audit_setup/install.properties SOLR_USERsolr …

音视频环境搭建

整体流程参考&#xff1a; Windows 10开发环境搭建 这里记录一下期间的遇到的问题&#xff1a; 下载的ffmpeg&#xff0c;将ffmpeg的bin目录添加到系统环境变量&#xff0c;然后将SDL的dll动态库拷贝到ffmpeg的bin目录下或将其所在的目录也添加到环境变量&#xff0c;不一定非要…

huawei USG6001v1学习---防火墙相关知识(2)

目录 1.安全策略 2.防火墙的状态检测和会话表技术 3.FTP 4.用户认证 5.认证策略 1.安全策略 传统包过滤技术 --- 其本质就是ACL访问控制列表&#xff0c;根据数据包的特征进行过滤&#xff0c;对比规则&#xff0c; 执行对应的动作&#xff1b; 这里数据包的特征 --- …

题解|2024暑期杭电多校01

【原文链接】 1001.循环位移 字符串 题目大意 给定两个字符串 A , B A,B A,B 。 定义 [ A ] [A] [A] 为字符串 A A A 的循环位移任意次可以得到的所有字符串的集合。 求 B B B 包含 [ A ] [A] [A] 中元素的个数。 解题思路 利用字符串Hash快速匹配。 将 [ A ] [A] …

switch可应用于哪些数据类型说说java中的数组和多维数组

switch可以用于哪些数据类型&#xff1f; switch是一种条件控制语句&#xff0c;根据不同的条件执行不同的代码块。switch使用一个或者多个不同的值来匹配某个表达式的值&#xff0c;并且根据结果来匹配不同的值。switch的语句基本格式 switch&#xff08;expression&#xf…

Web安全:未验证的重定向和转发.

Web安全&#xff1a;未验证的重定向和转发. 未验证的重定向和转发漏洞是一种常见的Web安全漏洞&#xff0c;它允许攻击者将用户重定向到一个恶意的URL&#xff0c;而不是预期的安全URL。这种漏洞通常发生在应用程序处理重定向和转发请求时&#xff0c;未能对目标URL进行适当的…

探索 PDF 转 Markdown 的项目:MinerU 和 pdfParser

pdfParser 项目是在MinerU 项目 的基础上开发的&#xff0c;增加了表格识别功能 MinerU&#xff1a;综合数据提取工具 MinerU 项目 是一款一站式、开源、高质量的数据提取工具&#xff0c;支持 PDF、网页和电子书的提取。其 Magic-PDF 模块可以将 PDF 转换为 Markdown 格式&a…