java设计模式-享元模式
享元模式
基本介绍
1、享元模式(flyweight Pattern),也叫作蝇量模式:运用在共享技术有效的支持大量细粒度的对象。
2、常用语系统底层开发,解决系统的性能问题。像 数据库连接,里面都是创建好的连接对象,在这些连接对象中有我们需要的则直接拿来用,
避免重新创建,入股偶没有我们需要的,则创建一个。
3、享元模式能够解决重复对象的内存浪费的问题,当系统中有大量相似对象,需要缓冲池时,不需要总是创建新对象,可以从缓冲池里面那拿,
这样可以降低系统内存,同时提高效率。
4、享元模式经典的应用常见就是池技术,String常量池,数据库连接池,缓冲池等等都是享元模式的应用,享元模式是池技术的重要实现方式。
原理图
1、FlyWeight是抽象的享元校色,他是产品的抽象类,同时定义出对象的外部状态和内部状态。
2、ConcreteFlyWeight具体的享元模式角色,是具体的产品类,实现抽象校色定义相关业务。
3、UnsharedConcreteFlyWeight是不可共享的角色。 一般不会出现在向原工厂。
4、FlyWeightFactory 向原工厂类,用于构建一个容器池(集合),同事提供从池中获取对象方法。
内部状态和外部状态
比如围棋、五子棋、跳棋,它们都有大量的棋子对象,围棋和五子棋只有黑白两色,跳棋颜 色多 一
点 ,所以棋子颜色就是棋子的内部状态;而各个棋子之间的差别就是位置的不同 ,当我们落子后
落子颜色是定的,但位置是变化的,所以棋子坐标就是棋子的外部状态
举个例子:围棋理 论上有 361 个空位可以放棋子 ,每盘棋都有可能有两三百个棋子对象产生,因为内存空间有限,
一台服务器很难支持更多的玩家玩围棋游戏,如果用享元模式来处理棋子,那么棋子对象就可以减少到只有两个实例,
这样就很好的解决了对象的开销问题
1、享元模式提出两个要求:细粒度和共享对象。这里就涉及到内部状态和外部状态了,即将对象的信息分为两个部分:内部状态和外部状态。
2、内部状态指对象共享出来的信息,存储在向原对象内部切不会随环境的改变而改变。
3、外部状态指对象的意义来的一个标记,是随环境改变而改变,不可共享的状态。
public abstract class WebSite {//抽象方法public abstract void use(User user);
}
@Data
public class User {private String name;public User(String name) {this.name = name;}
}
@Slf4j
public class ConcreteWebSite extends WebSite {//共享的部分,内部状态//网站发布的形式(类型)private String type = "";public ConcreteWebSite(String type) {this.type = type;}@Overridepublic void use(User user) {log.info("正在使用的网站:{},使用者是:{}",type,user.getName());}
}
public class WebSiteFactory {//集合,充电池的作用private HashMap<String, ConcreteWebSite> pool = new HashMap<>();//根据网站类型,返回一个网站,如果没有就创建一个,放入池中,并返回public WebSite getWebSiteCategory(String type) {if (!pool.containsKey(type)) {//没有就创建一个网站,并放入到池中。pool.put(type, new ConcreteWebSite(type));}return pool.get(type);}//获取网站分类的总数(池中有多少个世纪网站类型)public int getWebSiteCount(){return pool.size();}
}
@Slf4j
public class Client {public static void main(String[] args) {//创建一个工厂类WebSiteFactory factory=new WebSiteFactory();//创建一个以新闻形式发布的网站WebSite webSite=factory.getWebSiteCategory("新闻");webSite.use(new User("张三"));WebSite webSite1=factory.getWebSiteCategory("博客");webSite1.use(new User("张三1"));WebSite webSite2=factory.getWebSiteCategory("博客");webSite2.use(new User("张三2"));WebSite webSite3=factory.getWebSiteCategory("博客");webSite3.use(new User("张三3"));WebSite webSite4=factory.getWebSiteCategory("博客");webSite4.use(new User("张三4"));int webSiteCount = factory.getWebSiteCount();log.info("当前池中有{}个网站分类",webSiteCount);}
}
打印结果:
正在使用的网站:新闻,使用者是:张三
正在使用的网站:博客,使用者是:张三1
正在使用的网站:博客,使用者是:张三2
正在使用的网站:博客,使用者是:张三3
正在使用的网站:博客,使用者是:张三4
当前池中有2个网站分类
享元模式在jdk源码中的使用(Integer)
public class IntegerTest {public static void main(String[] args) {//如果Integer.valueOf(x) x在 -128 --- 127之间,使用的是享元模式// 如果不在范围内,则仍然new一个新对象//小结://1、在valueOf方法中,先判断值是否在IntegerCache中存在,如果不在,则新创建新的对象,否则直接从cache缓存池中取出返回,//2、valueOf方法, 就使用到了享元模式//3、如果使用到了valueOf方法得到一个Integer实例,范围在-128 - 127,直行速度比new快Integer x = Integer.valueOf(127);Integer y = new Integer(127);Integer z = Integer.valueOf(127);Integer w = new Integer(127);System.out.println(x.equals(y)); //trueSystem.out.println(x == y);//falseSystem.out.println(x == z);//trueSystem.out.println(w == x);//falseSystem.out.println(w == y);//falseSystem.out.println("=============================");Integer x1 = Integer.valueOf(200);Integer y1 = Integer.valueOf(200);System.out.println(x1==y1);//false}
}
源码分析
public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}//源码继续分析
private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint h = 127;String integerCacheHighPropValue =sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) {try {int i = parseInt(integerCacheHighPropValue);i = Math.max(i, 127);// Maximum array size is Integer.MAX_VALUEh = Math.min(i, Integer.MAX_VALUE - (-low) -1);} catch( NumberFormatException nfe) {// If the property cannot be parsed into an int, ignore it.}}high = h;cache = new Integer[(high - low) + 1];int j = low;for(int k = 0; k < cache.length; k++)cache[k] = new Integer(j++);// range [-128, 127] must be interned (JLS7 5.1.7)assert IntegerCache.high >= 127;}private IntegerCache() {}
}
使用注意事项
1、在享元模式这样理解,“享”就表示的共享,“元”表示对象。
2、系统中有大量对象,这些对象小号大量内存,并且对象的状态大部分可以外部化时,我们就可以考虑选用享元模式。
3、用唯一标识符判断,如果在内存中有,则返回这个唯一标识码所表示的对象。用HashMap/HashTable存储。
4、享元模式大大减少了对象的创建,降低了程序没存的占用,提高效率。
5、享元模式提高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态二改变,这是我们 使用享元模式需要注意的地方。
6、使用享元模式时,注意划分内部状态和外部状态,并且需要有一个工厂类加以控制。
7、享元模式进店的应用场景就是 需要缓冲池的场景,比如String常量池,数据里连接池。
相关文章:
java设计模式-享元模式
享元模式 基本介绍 1、享元模式(flyweight Pattern),也叫作蝇量模式:运用在共享技术有效的支持大量细粒度的对象。 2、常用语系统底层开发,解决系统的性能问题。像 数据库连接,里面都是创建好的连接对象,在这些连接对…...
Java 大视界 -- Java 大数据在智慧水利水资源调度与水情预测中的应用创新(180)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
自动驾驶---苹果又要造车了吗?
1 背景 巴菲特一直认为造车的企业是一个做 “苦生意” 的企业,可能苹果高层也意识到了这一点, 于是造车计划在去年被终止。 但2025年2月份,苹果公司署名发了一篇自动驾驶领域的论文《Robust Autonomy Emerges from Self-Play》,详…...
Redis主从复制:告别单身Redis!
目录 一、 为什么需要主从复制?🤔二、 如何搭建主从架构?前提条件✅步骤📁 创建工作目录📜 创建 Docker Compose 配置文件🚀 启动所有 Redis🔍 验证主从状态 💡 重要提示和后续改进 …...
PHP:将关联数组转换为索引数组的完整示例
处理之前的数据 头和行在一起显示 // 执行SQL查询后的原始数据(假设查询返回3条记录) $rawData [[wip_entity_name > JOB001,primary_item > ITEM001,primary_name > 主产品1,primary_desc > 主产品描述1,start_quantity > 100,quanti…...
27.[2019红帽杯]easyRE1(保姆教程)
收到文件,.elf 文件,ExeinfoPE查看一下基础信息。无壳,64bit。 把文件拖入IDA工具,查看一下。 点击关键字,ctrl x 交叉搜索一下位置,跟进,顺便菜单左侧 Edit --> Plugins--> findcrypt …...
【Redis】Redis实现分布式锁
1. 基于Redis 1.1 加锁 setnx lockKey uniqueValue1.2 解锁 基于Lua脚本保证解锁的原子性。Redis在执行Lua脚本时,可以以原子性的方式执行,确保原子性。 if redis.call("get", keys[1]) argv[1] then return redis.call("del", …...
AI大模型底层技术——Scaling Law
0. 定义 Scaling Law 是描述 AI 模型性能随关键因素(如参数量、数据量、计算量)增长而变化的数学规律,通常表现为幂律关系。 历史里程碑: **OpenAI 2020 年论文首次系统提出语言模型的缩放定律**DeepMind、Google 等机构后续发表…...
Spring MVC 国际化机制详解(MessageSource 接口体系)
Spring MVC 国际化机制详解(MessageSource 接口体系) 1. 核心接口与实现类详解 接口/类名描述功能特性适用场景MessageSource核心接口,定义消息解析能力支持参数化消息(如{0}占位符)所有国际化场景的基础接口Resource…...
java学习笔记13——IO流
File 类的使用 常用构造器 路径分隔符 常用方法 File类的获取功能和重命名功能 File 类的判断功能 File类的创建功能和删除功能 File 类的使用 总结: 1.File类的理解 > File类位于java.io包下,本章中涉及到的相关流也都声明在java.io包下 > File…...
防DDoS流量清洗核心机制解析
本文深度剖析DDoS流量清洗技术演进路径,揭示混合云清洗系统的四层过滤架构,结合2023年新型反射攻击案例,提出基于AI行为分析的动态防御策略。通过Gartner最新攻防效能数据与金融行业实战方案,阐明流量清洗系统在误判率、清洗延迟、…...
边缘计算革命:低功耗GPU在自动驾驶实时决策中的应用
边缘计算革命:低功耗GPU在自动驾驶实时决策中的应用 ——分析NVIDIA Jetson与华为昇腾的嵌入式方案差异 一、自动驾驶的实时决策挑战与边缘计算需求 自动驾驶系统需在30ms内完成环境感知、路径规划与车辆控制的全流程闭环。传统云端计算受限于网络延迟…...
ubuntu24.04-MyEclipse的项目导入到 IDEA中
用myeclipse创建的一个web项目, jdk1.7,tomcat7,mysql8.0,导入到idea项目中 1.导入现有项目 1.打开IDEA,选择“Import Project”进入下一步 2.选择所需要导入的项目,点击“OK” 3.点击创建一个新的项目,然后下一步 4.直接点…...
基于SpringBoot的律师事务所案件管理系统【附源码】
基于SpringBoot的律师事务所案件管理系统(源码L文说明文档) 目录 4 系统设计 4.1界面设计原则 4.2功能结构设计 4.3数据库设计 4.3.1属性图 4.3.2 数据库物理设计 5 系统实现 5.1客户信息管理 5.2 律师…...
电力网关:推动电力物联网及电力通信系统革新
在“双碳”目标与新型电力系统建设的背景下,电力行业正加速向数字化、智能化、绿色化转型。作为国内领先的电力物联网解决方案提供商,厦门计讯物联科技有限公司(以下简称“计讯物联”)依托自主研发的电力专用网关、边缘计算平台及…...
Android系统的Wi-Fi系统框架和详细启动流程
目录 一、前言 二、系统架构层次 1、应用层 2、Framework层 3、HAL层 4、驱动层 三、Wi-Fi 目录树结构 四、系统流程 1、应用层请求 2、Wi-Fi管理服务处理 3、硬件交互 4、数据处理与事件通知 5.连接管理 6.状态维护 五、WiFi启动流程及函数调用…...
Scala基础知识8
集合计算高级函数 包括过滤、转换或映射、扁平化、扁平化加映射、分组、简化(归约),折叠 过滤:遍历一个集合并从中获取满足指定条件的元素组成一个新的集合。 转换或映射:将原始集合中的元素映射到某个函数中。 扁平化:取消嵌套格式&…...
SwiftUI 本地推送(Local Notification)教程目录
1. 本地推送简介 1.1 什么是本地推送?1.2 本地推送的应用场景(提醒、定时任务、用户交互等)1.3 本地推送与远程推送的区别 2. 前提条件 2.1 开发环境要求(Xcode 13、iOS 15)2.2 需要的基础知识(SwiftUI …...
大数据技术与Scala
集合高级函数 过滤 通过条件筛选集合元素,返回新集合。 映射 对每个元素应用函数,生成新集集合 扁平化 将嵌套集合展平为单层集合。 扁平化映射 先映射后展平,常用于拆分字符串。 分组 按规则将元素分组为Map结构。 归约 …...
golang通过飞书邮件服务API发送邮件功能详解
一.需求 需要实现通过飞书邮件服务API发送邮件验证码功能:用户输入邮箱, 点击发送邮件,然后发送邮件验证码, 这里验证码有过期时间, 保存到redis缓存中 二.实现 实现的部分代码如下: 控制器部分代码 // 发送邮件控制器 func EmailSendController(userId uint64, m proto.Messa…...
BoostSearch搜索引擎项目 —— 测试用例设计 + web自动化测试代码
web自动化代码: https://gitee.com/chicken-c/boost-search/tree/master/AutoTest...
MySQL学习笔记集--触发器
触发器 MySQL触发器(Trigger)是一种特殊的存储过程,它在指定的数据库表上指定的事件(INSERT、UPDATE、DELETE)之前或之后自动执行。触发器可以用来强制执行复杂的业务逻辑、数据完整性规则、自动更新数据等。 触发器…...
算力驱动未来:从边缘计算到高阶AI的算力革命
算力驱动未来:从边缘计算到高阶AI的算力革命 摘要 本文深入探讨了不同算力水平(20TOPS至160TOPS)在人工智能领域的多样化应用场景。从边缘计算的实时目标检测到自动驾驶的多传感器融合,从自然语言处理的大模型应用到AI for Scie…...
4.8刷题记录(双指针)
今天刷的部分是代码随想录中的双指针专题代码随想录 由于里面包含的题目大部分之前刷过,并且用双指针做过。所以今天仅仅复习,不再进行代码的搬运。 1.19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) 分析:此题无…...
在shell脚本中,$@和$#的区别与联系
在 Shell 脚本里,$ 和 $* 都是用于表示传递给脚本或函数的所有参数,下面详细介绍它们的区别与联系。 联系 表示所有参数:二者都能够代表传递给脚本或者函数的全部参数。当你在执行脚本时带上了多个参数,$ 和 $* 都能把这些参数呈…...
IP节点详解及国内IP节点获取指南
获取国内IP节点通常涉及网络技术或数据资源的使用,IP地址作为网络设备的唯一标识,对于网络连接和通信至关重要。详细介绍几种修改网络IP地址的常用方法,无论是对于家庭用户还是企业用户,希望能找到适合自己的解决方案。以下是方法…...
Google Play上架:解决android studio缓存问题(内容清理不干净导致拒审)
在as打包中,经常会遇到改变工程参数或者对应文件参数的情况,比如 修改android gradle版本 快捷键:ctrl + alt + shift + s 修改SDK文件路径 快捷键:ctrl + alt + shift + s 修改Gradle存储下载文件的默认位置 快捷键:ctrl + alt + s 先打开设置 修改compile...
蓝桥杯备赛 Day 21 图论基础
图的基础 ![[图的基础.png]] 1.图的存储方式 (1)邻接表(常用) vector<pair<int,int>> g[N]; //g[x]存放x的所有出点信息,二维数组 g[i][j]{first,second},first是从i出发的第j个出点,second表示边权 例如上图: g[1]{{2,0}.{3,0}} g[6]{{3,7}} g[4]{{5,0},{6,0}…...
MySQL数据库应用技术试卷
建一个以自己名字拼音为命名的数据库。(3分) CREATE DATABASE example; 令这个数据库为当前所使用的数据库。(2分) USE example; 写出如下student表结构语句。(95分) 表1: 列名 数据类型 …...
openssl源码分析之加密模式(modes)
openssl实现分组加密模式(例如AES128-CBC的CBC部分)的模块名字叫做modes,源代码位于 https://gitee.com/gh_mirrors/openssl/tree/master/crypto/modes 博主又打不开github了TT,只能找个gitee镜像 头文件是modes.h。 该模块目前…...
【Unity】Unity Transform缩放控制教程:实现3D模型缩放交互,支持按钮/鼠标/手势操作
【Unity 】Transform缩放控制教程:实现3D模型缩放交互,支持按钮/鼠标/手势操作 在Unity开发中,Transform组件承担着场景中物体的空间信息控制,包括位置、旋转和缩放。而缩放(Scale)操作,作为三…...
集成nacos2.2.1出现的错误汇总
总结 1.jdk问题 jdk要一致 2.idea使用问题 idea启动nacos要配置,idea启动类要启动两次,并配置两次vm参数 3.项目依赖问题 依赖要正确添加,有的模块就是不能用公共模块的pom配置,需要独立配置,先后启动顺序也要注意…...
从零到有的游戏开发(visual studio 2022 + easyx.h)
引言 本文章适用于C语言初学者掌握基本的游戏开发, 我将用详细的步骤引领大家如何开发属于自己的游戏。 作者温馨提示:不要认为开发游戏很难,一些基本的游戏逻辑其实很简单, 关于游戏的开发环境也不用担心,我会详细…...
海外高防服务器延迟优化——跨国业务安全加速的底层逻辑
本文深度解析海外高防服务器延迟优化的技术实现路径,揭示跨国业务场景下DDoS防护与网络性能的平衡法则。从物理线路选择到协议栈调优,从流量调度算法到安全检测机制重构,系统阐述降低20ms-50ms延迟的工程实践方案,并附2023年东南亚…...
常用环境部署(二十六)——Centos搭建MQTT服务端EMQX
1、安装docker https://blog.csdn.net/wd520521/article/details/112609796?spm1011.2415.3001.5331 2、安装EMQX4.4.4 (1)使用docker pull指令安装emqx镜像 docker pull emqx/emqx:4.4.4 (2)查看镜像 docker images 3、启…...
ecovadis认证基本概述,ecovadis认证审核有效期
EcoVadis认证基本概述 1. 什么是EcoVadis认证? EcoVadis是全球领先的企业可持续发展(ESG)评级平台,专注于评估企业在**环境(E)、劳工与人权(S)、商业道德(L)…...
2.8.4 iOS覆盖率SDK开发
iOS系统的覆盖率SDK,通过搭建本地的pod仓库,直接在podfile中添加指定的下载地址,就可以实现对被测试的app注入覆盖率SDK。 2.8.4.1 开发iOS覆盖率获取Pod私有库 在网上查找了相应的开发方法后,决定开发自己的依赖库,开发方法及步骤如下: 1,开发新的包 (1)通过Xcode创…...
Redhat(6)-ansible-变量
变量 1.作用域 Global scope:命令行中设置。 Play scope:play中设置。 Host scope :inventory中定义、facts收集或任务中注册,在主机组和主机上设置。 1.全局变量 1.1cmd命令 #1.全局变量 #显示变量 echo %PATH1.2.ansible变量 全局变量 var变量不加…...
麦科信光隔离探头在碳化硅(SiC)MOSFET动态测试中的应用
碳化硅(SiC)MOSFET 是基于宽禁带半导体材料碳化硅(SiC)制造的金属氧化物半导体场效应晶体管,相较于传统硅(Si)MOSFET,具有更高的击穿电压、更低的导通电阻、更快的开关速度以及更优异…...
android audiorecord
这里写目录标题 初始化失败记录 AudioRecord 初始化及参数介绍基本初始化参数详解1. audioSource (音频源)2. sampleRateInHz (采样率)3. channelConfig (声道配置)4. audioFormat (音频格式)5. bufferSizeInBytes (缓冲区大小) 完整初始化示例使用注意事项 参考地址 初始化失败…...
有一个变量 在有些线程没有加锁 有些线程加锁了,那我在这些加锁的线程中能起到对应的作用吗
这是一个非常经典、但也很危险的问题。 🧨 简单结论: 如果一个变量在某些线程访问时没有加锁,即使其他线程对它加了锁,也: ❌ 不能保证线程安全! ❌ 加锁的部分不会“保护”未加锁的部分! &am…...
【人工智能】AI大模型开发数学基础指南
目录 学习内容**1. 线性代数****2. 概率与统计****3. 微积分****4. 优化理论****5. 信息论****6. 数值计算****7. 离散数学****8. 统计学进阶****如何学习?****总结** 如何学习**1. 明确学习目标****2. 分阶段学习计划****阶段 1:夯实基础****阶段 2&…...
直流减速电机控制实验:Simulink应用层开发(3)
文章目录 1 阶段目标2 单元测试方法3 单元测试过程3.1 按键指令识别测试3.2 电机状态转换测试4 代码生成5 总结1 阶段目标 本文是《直流减速电机控制实验》的第四部分,会通过图文结合的方式,手把手带读者操作Simulink工具进行直流减速电机的应用层开发。 本章主要将《直流减…...
隔行换色总结
功能效果展示: 第一种思路: 使用数组,将数组的内容渲染到页面上,序号也就是将数组的下标输出到第一个td上,将数组的内容输出到第二个td上,(使用拼接字符串) 具体操作: …...
【kind管理脚本-2】脚本使用说明文档 —— 便捷使用 kind 创建、删除、管理集群脚本
当然可以,以下是为你这份 Kind 管理脚本写的一份使用说明文档,可作为 README.md 或内部文档使用: 🚀 Kind 管理脚本说明文档 本脚本是一个便捷的工具,帮助你快速创建、管理和诊断基于 Kind (Kubernetes IN Docker) 的…...
Python星球日记 - 第13天:封装、继承与多态
🌟引言: 上一篇:Python星球日记 - 第12天:面向对象编程(OOP)基础 名人说:不要人夸颜色好,只留清气满乾坤(王冕《墨梅》) 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、引言二、封装的概念与实现1. 公有属性与私有属性2. 使用getter和sett…...
基于AT89C52单片机的GSM上报智能家居报警温度烟雾防盗系统
点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/90579530?spm1001.2014.3001.5503 功能介绍: 1、功能:具有温度、烟雾、入侵报警功能,采用LCD1602液晶显示屏实时显示温度值与…...
北重数控滑台厂家:机器人地轨究竟是如何运作的,又在哪些领域发光发热呢?
机器人地轨是指利用机器人技术在地面上移动或执行任务的轨道系统。这种系统通常包括导轨、传动装置、传感器和控制系统等组成部分。机器人地轨的运作原理是通过控制传动装置沿着导轨移动,同时利用传感器获取周围环境信息并通过控制系统进行实时调节。 机器人地轨在…...
2025最新系统 Git 教程(三)
2.3 Git 基础 - 查看提交历史 查看提交历史 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 git log 命令。 我们使用一个非常简单的 simplegit 项目作为示例。 运行下面的命令获取该项目&…...
显示器各类异常处理方法
显示器各类异常处理方法 导航 文章目录 显示器各类异常处理方法导航画面无显示/黑屏/无HDMI信号输入显示器闪烁显示器花屏显示画面模糊或扭曲显示器颜色异常显示器出现死点或亮点 画面无显示/黑屏/无HDMI信号输入 首先应该检查的是显示器电源(真的有人弄掉电源…...