(十 二)趣学设计模式 之 享元模式!
目录
- 一、 啥是享元模式?
- 二、 为什么要用享元模式?
- 三、 享元模式的实现方式
- 四、 享元模式的优缺点
- 五、 享元模式的应用场景
- 六、 总结
🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解组合模式请看: (十 一)趣学设计模式 之 组合模式!
✨更多请看个人主页: 码熔burning
这篇文章带你详细认识一下设计模式中的享元模式
一、 啥是享元模式?
想象一下,你正在玩一个大型的在线游戏 🎮。 游戏中有成千上万的士兵 💂,每个士兵都有自己的位置、生命值、装备等等。 如果为每个士兵都创建一个完整的对象,会消耗大量的内存 🧠。 但是,很多士兵的外观、属性都是相同的,只有位置不同。
享元模式,就是运用共享技术有效地支持大量细粒度的对象! 享元模式通过共享尽可能多的对象来最小化内存使用 💾。
简单来说,就是把对象的状态分成内部状态和外部状态,共享内部状态,减少对象数量! ♻️
- 你的程序需要创建大量的相似对象: 就像游戏中的士兵 🎮💂!
- 对象的很多状态都可以共享: 就像士兵的外观、属性 🎮!
- 你想减少内存消耗: 就像你想让游戏运行更流畅 🧠!
二、 为什么要用享元模式?
用享元模式,好处多多 👍:
- 减少内存消耗: 通过共享对象,减少内存占用 💾!
- 提高性能: 减少对象创建和销毁的开销 🚀!
- 提高系统扩展性: 可以支持更多的对象 ➕!
三、 享元模式的实现方式
享元模式主要包含以下几个角色:
- Flyweight(享元): 定义享元对象的接口,声明可以被共享的内部状态,并提供接受外部状态的方法。 🎮💂 (比如:士兵的基类)
- ConcreteFlyweight(具体享元): 实现享元接口,存储内部状态。 🎮💂 (比如:具体的士兵对象)
- UnsharedConcreteFlyweight(非共享具体享元): 不是共享的享元对象,通常包含一些不能被共享的状态。 (比如:拥有特殊装备的士兵)
- FlyweightFactory(享元工厂): 创建和管理享元对象,确保享元对象可以被共享。 🏭 (比如:士兵工厂)
- Client(客户端): 使用享元对象,并提供外部状态。 🎮 (比如:游戏客户端)
内部状态: 指的是对象可以共享的状态,存储在享元对象内部,不会随着环境改变而改变。 (比如:士兵的外观、属性)
外部状态: 指的是对象不能共享的状态,需要由客户端提供,会随着环境改变而改变。 (比如:士兵的位置、生命值)
代码示例:
import java.util.HashMap;
import java.util.Map;// 享元:士兵接口
public interface Soldier {void display(int x, int y); // 显示士兵
}// 具体享元:士兵
public class ConcreteSoldier implements Soldier {private String model; // 士兵模型public ConcreteSoldier(String model) {this.model = model;}@Overridepublic void display(int x, int y) {System.out.println("士兵模型:" + model + ",位置:(" + x + ", " + y + ")");}
}// 享元工厂:士兵工厂
public class SoldierFactory {private static Map<String, Soldier> soldierMap = new HashMap<>(); // 存储士兵对象public static Soldier getSoldier(String model) {Soldier soldier = soldierMap.get(model);if (soldier == null) {soldier = new ConcreteSoldier(model);soldierMap.put(model, soldier);}return soldier;}
}// 客户端
public class Client {public static void main(String[] args) {Soldier soldier1 = SoldierFactory.getSoldier("步兵"); // 获取步兵soldier1.display(10, 20); // 显示步兵Soldier soldier2 = SoldierFactory.getSoldier("步兵"); // 获取步兵soldier2.display(30, 40); // 显示步兵Soldier soldier3 = SoldierFactory.getSoldier("骑兵"); // 获取骑兵soldier3.display(50, 60); // 显示骑兵System.out.println("士兵数量:" + SoldierFactory.soldierMap.size()); // 输出士兵数量}
}
分析:
Soldier
是享元接口,定义了士兵的显示方法。ConcreteSoldier
是具体享元,实现了士兵接口,存储了士兵的模型。SoldierFactory
是享元工厂,创建和管理士兵对象,确保相同模型的士兵对象只创建一个。
输出结果:
士兵模型:步兵,位置:(10, 20)
士兵模型:步兵,位置:(30, 40)
士兵模型:骑兵,位置:(50, 60)
士兵数量:2
可以看到,虽然创建了三个士兵对象,但是实际只创建了两个士兵对象,因为步兵对象被共享了。
四、 享元模式的优缺点
优点:
- 减少内存消耗 💾!
- 提高性能 🚀!
- 提高系统扩展性 ➕!
缺点:
- 增加了系统的复杂度 😫!
- 需要分离内部状态和外部状态,设计难度较高 🧠!
- 共享对象的状态不可修改,否则会影响其他使用该对象的客户端 🔒!
五、 享元模式的应用场景
- 当你的程序需要创建大量的相似对象时: 就像游戏中的士兵 🎮💂!
- 对象的很多状态都可以共享: 就像士兵的外观、属性 🎮!
- 你想减少内存消耗: 就像你想让游戏运行更流畅 🧠!
- 文本编辑器: 文本编辑器可以使用享元模式来共享字符对象,减少内存消耗。
- 数据库连接池: 数据库连接池可以使用享元模式来共享数据库连接对象,提高性能。
六、 总结
- 享元模式就像把对象的状态分成内部状态和外部状态,共享内部状态,减少对象数量! ♻️
- 主要包含享元、具体享元、非共享具体享元和享元工厂四个角色! 🎭
- 优点是减少内存消耗、提高性能、提高系统扩展性! 👍
- 缺点是增加复杂度、设计难度较高、共享对象的状态不可修改! 👎
- 适用于需要创建大量的相似对象,且对象的很多状态都可以共享的场景! 🎯
希望这篇文章能让你彻底理解享元模式! 💯 祝你学习愉快! 😄
看完请看:(十 三)趣学设计模式 之 模版方法模式!
相关文章:

(十 二)趣学设计模式 之 享元模式!
目录 一、 啥是享元模式?二、 为什么要用享元模式?三、 享元模式的实现方式四、 享元模式的优缺点五、 享元模式的应用场景六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支…...

leetcode第77题组合
原题出于leetcode第77题https://leetcode.cn/problems/combinations/ 1.树型结构 2.回溯三部曲 递归函数的参数和返回值 确定终止条件 单层递归逻辑 3.代码 二维数组result 一维数组path void backtracking(n,k,startindex){if(path.sizek){result.append(path);return ;}…...

Linux | Ubuntu 与 Windows 双系统安装 / 高频故障 / UEFI 安全引导禁用
注:本文为 “buntu 与 Windows 双系统及高频故障解决” 相关文章合辑。 英文引文,机翻未校。 How to install Ubuntu 20.04 and dual boot alongside Windows 10 如何将 Ubuntu 20.04 和双启动与 Windows 10 一起安装 Dave’s RoboShack Published in…...

Docker入门指南:Windows下docker配置镜像源加速下载
Windows下docker配置镜像源加速下载 docker的官方镜像是海外仓库,默认下载耗时较长,而且经常出现断站的现象,因此需要配置国内镜像源。 国内镜像源概述 国内现有如下镜像源可以使用 "http://hub-mirror.c.163.com", "http…...

web前端基础修炼手册
目录 引言 1. 安装插件 2. 前端三剑客 3. 开发者模式 第一章 HTML 1.文件结构 2. 常见标签 2.1 注释标签 2.2 标题标签 2.3 段落标签 2.4 换行标签 2.5 格式化标签 2.6 图片标签 2.7 超链接标签 2.8 表格标签 2.9 列表标签 2.10 form标签 2.11 input 标签 2.12 la…...
【无标题】Ubuntu22.04编译视觉十四讲slambook2 ch4时fmt库的报错
Ubuntu22.04编译视觉十四讲slambook2 ch4时fmt库的报错 cmake ..顺利,make后出现如下报错: in function std::make_unsigned<int>::type fmt::v8::detail::to_unsigned<int>(int): trajectoryError.cpp:(.text._ZN3fmt2v86detail11to_unsi…...

macos下myslq图形化工具之Sequel Ace
什么是Sequel Ace 官方github:https://github.com/Sequel-Ace/Sequel-Ace Sequel Ace 是一款快速、易于使用的 Mac 数据库管理应用程序,用于处理 MySQL 和 MariaDB 数据库。 Sequel Ace 是一款开源项目,采用 MIT 许可证。用户可以通过 Ope…...
【AHK】资源管理器自动化办公实例/自动连点设置
此处为一个自动连续点击打开检查的自动化操作案例,没有quicker的鼠键录制,不常用了,做个备份 #MaxThreadsPerHotkey 2 ; 这个是核心!!!!确保可以同时运行多个热键或标签global isRunning : tru…...
通用查询类接口数据更新的另类实现
文章目录 一、简要概述二、java工程实现1. 定义main方法2. 测试运行3. 源码放送 一、简要概述 我们在通用查询类接口开发的另类思路中,关于接口数据的更新,提出了两种方案: 文件监听 #mermaid-svg-oJQjD6jQ8T19XlHA {font-family:"tre…...
Linux ls 命令
Linux ls(英文全拼: list directory contents)命令用于显示指定工作目录下之内容(列出目前工作目录所含的文件及子目录)。 语法 ls [-alrtAFR] [name...] 参数 : -a 显示所有文件及目录 (. 开头的隐藏文件也会列出)-d 只列出目…...

【问题记录】Go项目Docker中的consul访问主机8080端口被拒绝
【问题记录】Go项目Docker中的consul访问主机8080端口被拒绝 问题展示解决办法 问题展示 在使用docker中的consul服务的时候,通过命令行注册相应的服务(比如cloudwego项目的demo_proto以及user服务)失败。 解决办法 经过分析,是…...
面试题:说一下你对DDD的了解?
面试题:说一下你对DDD的了解? 在面试中,关于 DDD(领域驱动设计,Domain-Driven Design) 的问题是一个常见的技术考察点。DDD 是一种软件设计方法论,旨在通过深入理解业务领域来构建复杂的软件系统。以下是一个清晰、详细的回答模板,帮助你在面试中脱颖而出: DDD 的定义…...

React低代码项目:问卷编辑器 I
问卷编辑器 Date: February 20, 2025 4:17 PM (GMT8) 目标 完成问卷编辑器的设计和开发完成复杂系统的 UI 组件拆分完成复杂系统的数据结构设计 内容 需求分析技术方案设计开发 注意事项: 需求指导设计,设计指导开发。前两步很重要页面复杂的话&…...
蓝桥杯2024年真题java B组 【H.拼十字】
蓝桥杯2024年真题java B组 【H.拼十字】 原题链接:拼十字 思路: 使用树状数组或线段树解决。 先将输入的信息存入到一个n行3列的数组中,将信息排序,按照长度小到大,长相同时,宽度小到大 排序。 建立三个…...

Spring MVC 程序开发(1)
目录 1、什么是 SpringMVC2、返回数据2.1、返回 JSON 对象2.2、请求转发2.3、请求重定向2.4、自定义返回的内容 1、什么是 SpringMVC 1、Tomcat 和 Servlet 分别是什么?有什么关系? Servlet 是 java 官方定义的 web 开发的标准规范;Tomcat 是…...

PyCharm接入本地部署DeepSeek 实现AI编程!【支持windows与linux】
今天尝试在pycharm上接入了本地部署的deepseek,实现了AI编程,体验还是很棒的。下面详细叙述整个安装过程。 本次搭建的框架组合是 DeepSeek-r1:1.5b/7b Pycharm专业版或者社区版 Proxy AI(CodeGPT) 首先了解不同版本的deepsee…...

Linux服务升级:Almalinux 升级 DeepSeek-R1
目录 一、实验 1.环境 2.Almalinux 部署 Ollama 3.Almalinux 升级 DeepSeek-R1 4.Almalinux 部署 docker 5. docker 部署 DeepSeek-R1 6.Almalinux 部署 Cpolar (内网穿透) 7.使用cpolar内网穿透 二、问题 1.构建容器失败 一、实验 1.环境 (1)…...

Linux操作系统5- 补充知识(可重入函数,volatile关键字,SIGCHLD信号)
上篇文章:Linux操作系统5-进程信号3(信号的捕捉流程,信号集,sigaction)-CSDN博客 本篇Gitee仓库:myLerningCode/l26 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 目录 一. 可重入…...

ctfshow刷题笔记—栈溢出—pwn61~pwn64
目录 前言 一、pwn61(输出了什么?) 二、pwn62(短了一点) 三、pwn63(又短了一点) 四、pwn64(有时候开启某种保护并不代表这条路不通) 五、一些shellcode 前言 这几道都是与shellcode有关的题,实在是…...
java23种设计模式-责任链模式
责任链模式(Chain of Responsibility Pattern)学习笔记 编程相关书籍分享:https://blog.csdn.net/weixin_47763579/article/details/145855793 DeepSeek使用技巧pdf资料分享:https://blog.csdn.net/weixin_47763579/article/details/145884039 🌟 模式定义 责任链模式是…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...