享元模式 rust和java的实现
文章目录
- 享元模式
- 介绍
- 实现
- java
- rust
- 实现代码
- rust仓库
- rust仓库
享元模式
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式,可使我们能够重复利用对象,使我们减少重复创建和销毁对象造成的开销,从而提升程序的运行效率。
享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。我们将通过创建 5 个对象来画出 20 个分布于不同位置的圆来演示这种模式。由于只有 5 种可用的颜色,所以 color 属性被用来检查现有的 Circle 对象。
介绍
-
意图:运用共享技术有效地支持大量细粒度的对象。
-
主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
-
何时使用:
- 系统中有大量重可复利用的对象。
- 这些对象消耗大量内。
- 对象的创建和销毁较为浪费系统资源。
- 这些对象的状态大部分可以外部化。
- 这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。
- 系统不依赖于这些对象身份,这些对象是不可分辨的。
-
应用实例: 1、JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。 2、数据库的连接池。
-
优点:大大减少对象的创建,降低系统的内存,使效率提高。
-
缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
实现
我们将创建一个 Shape 接口和实现了 Shape 接口的实体类 Circle。下一步是定义工厂类 ShapeFactory。
ShapeFactory 有一个 Circle 的 HashMap,其中键名为 Circle 对象的颜色。无论何时接收到请求,都会创建一个特定颜色的圆。ShapeFactory 检查它的 HashMap 中的 circle 对象,如果找到 Circle 对象,则返回该对象,否则将创建一个存储在 hashmap 中以备后续使用的新对象,并把该对象返回到客户端。
FlyWeightPatternDemo 类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(red / green / blue/ black / white),以便获取它所需对象的颜色。
享元模式的 UML 图

java
步骤 1
创建一个接口。
Shape.java
public interface Shape {void draw();
}
步骤 2
创建实现接口的实体类。
Circle.java
public class Circle implements Shape {private String color;private int x;private int y;private int radius;public Circle(String color){this.color = color; }public void setX(int x) {this.x = x;}public void setY(int y) {this.y = y;}public void setRadius(int radius) {this.radius = radius;}@Overridepublic void draw() {System.out.println("Circle: Draw() [Color : " + color +", x : " + x +", y :" + y +", radius :" + radius);}
}
步骤 3
创建一个工厂,生成基于给定信息的实体类的对象,我梦采用hashmap结构存储我们的数据。
ShapeFactory.java
import java.util.HashMap;public class ShapeFactory {private static final HashMap<String, Shape> circleMap = new HashMap<>();public static Shape getCircle(String color) {Circle circle = (Circle)circleMap.get(color);if(circle == null) {circle = new Circle(color);circleMap.put(color, circle);System.out.println("Creating circle of color : " + color);}return circle;}
}
步骤 4
使用该工厂,通过传递颜色信息来获取实体类的对象,并且我们是通过颜色判断,是否是需要同一个对象。
FlyweightPatternDemo.java
public class FlyweightPatternDemo {private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" };public static void main(String[] args) {for(int i=0; i < 20; ++i) {Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor());circle.setX(getRandomX());circle.setY(getRandomY());circle.setRadius(100);circle.draw();}}private static String getRandomColor() {return colors[(int)(Math.random()*colors.length)];}private static int getRandomX() {return (int)(Math.random()*100 );}private static int getRandomY() {return (int)(Math.random()*100);}
}
步骤 5
执行程序,输出结果:
Creating circle of color : Black
Circle: Draw() [Color : Black, x : 36, y :71, radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 27, y :27, radius :100
Creating circle of color : White
Circle: Draw() [Color : White, x : 64, y :10, radius :100
Creating circle of color : Red
Circle: Draw() [Color : Red, x : 15, y :44, radius :100
Circle: Draw() [Color : Green, x : 19, y :10, radius :100
Circle: Draw() [Color : Green, x : 94, y :32, radius :100
Circle: Draw() [Color : White, x : 69, y :98, radius :100
Creating circle of color : Blue
rust
rust和java的实现相似,就不再赘述过程,不过需要注意的是,在rust中官方没有提供rand包我们需要引入第三方包,所以我们需要在Cargo.toml文件引入以下依赖
[dependencies]
rand = "0.8.5"
实现代码
use std::{collections::HashMap};
use rand::{Rng};
// 创建形状接口
trait Shape {fn draw(&self);
}
struct Circle{color:String,x:i32,y:i32,radius:i32,
}
impl Shape for Circle {fn draw(&self) {println!("Circle: Draw() [Color: {},x: {},y: {},radius: {}]",self.color,self.x,self.y,self.radius);}
}
impl Circle {fn new(color:String)->Circle {Circle{color:color,x:0,y:0,radius:0}}
}
// 设置形状工场,进行管理
struct ShapeFactory{circle_map:HashMap<String,Circle>
}
impl ShapeFactory {fn get_circle(&mut self,color:&str)->&mut Circle{match self.circle_map.get(color) {None=>{self.circle_map.insert(color.to_owned(),Circle::new(color.to_owned())); println!("Creating circle of color : {}" ,color);}Some(_)=>{println!("已有触发享元")}};self.circle_map.get_mut(color).unwrap()}
}
fn get_rand_color()->& 'static str {COLORS[rand::thread_rng().gen_range(0..COLORS.len())]
}
fn get_randx()->i32 {rand::thread_rng().gen_range(0..100)
}
fn get_randy()->i32 {rand::thread_rng().gen_range(0..100)
}
const COLORS: [&str; 5]=["Red", "Green", "Blue", "White", "Black" ];fn main() {let mut shape_factory=ShapeFactory{circle_map:HashMap::new()};for _x in 1..=5 {let color=shape_factory.get_circle(get_rand_color());color.x=get_randx();color.y=get_randy();color.radius=100;color.draw();}// println!("{}",get_rand_color());}
rust仓库
rust仓库
https://github.com/onenewcode/design.git
本教程项目在bin文件夹下的flyweight.rs文件中
相关文章:
享元模式 rust和java的实现
文章目录 享元模式介绍实现javarust实现代码 rust仓库rust仓库 享元模式 享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应…...
XmlElement注解在Java的数组属性上,以产生多个相同的XML元素
例如,下面这段XML数据,有多个data元素,并且它们级别相同: <?xml version"1.0" encoding"UTF-8"?><request><reqtype>05</reqtype><secret>test</secret><body><userid&…...
SQLServer 数字加千分位 用FORMAT函数强转不管多大位数
问题 CONVERT ( money, CONVERT ( money, CAST ( round( FTP_AMOUNT, 2 ) AS NUMERIC ( 20, 2 ) ) ) 1 ) AS FTP_AMOUNT用的money函数 结果空间不足,无法将 money 值转换为 varchar。 可以强转 select FORMAT(CAST ( round( ‘-8926143870680.62000000’, 2 ) AS N…...
说说mvc和mvvm的区别和联系
mvvm 与mvc mvvm 与mvcmvc和mvvm的区别和联系 举例说明mvvm与mvc MVC是一种用于构建应用程序的架构模式,它也将应用程序的逻辑和界面分离。它由三个主要组件组成: 模型(Model):表示应用程序的数据和业务逻辑。视图&a…...
linux rsyslog综合实战2
本次我们通过rsyslog服务将A节点服务器上的两个(E.g:多个日志也可以)日志(Path:/var/log/245-1.log、245-2.log)实时同步到B节点服务器目录下(Path:/opt/rsyslog/245) 1.rsyslog架构 2.环境信息 环境信息 HostnameIpAddressOS versionModuleNotersyslog1192.168.10.245CentOS…...
AcWing 4. 多重背包问题 I 学习笔记
有 N� 种物品和一个容量是 V� 的背包。 第 i� 种物品最多有 si�� 件,每件体积是 vi��,价值是 wi��。 求解将哪些物品装入背包,可使物…...
解决selenium使用chrome下载文件(如pdf)时,反而打开浏览器的预览界面
文章目录 解决方法完整的配置 解决方法 在初始化浏览器的时候,添加以下配置即可: option webdriver.ChromeOptions()prefs {"profile.managed_default_content_settings.images": 2, # 禁止加载图片# permissions.default.stylesheet: 2, …...
2024年山东省职业院校技能大赛中职组“网络安全”赛项竞赛试题-C
2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-C 一、竞赛时间 总计:360分钟 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A、B模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略设置 A-3 流量完整性保护 A-4 …...
基于Python实现用于实时监控和分析 MySQL 服务器的性能指标和相关信息工具源码
MySQL命令行监控工具 - mysqlstat 介绍 mysqlstat 是一个命令行工具,用于实时监控和分析 MySQL 服务器的性能指标和相关信息。 它可以帮助 DBA(数据库管理员)和开发人员定位和解决数据库性能问题。 以下是 mysqlstat 工具的主要功能&#…...
Android 10-13鼠标右键返回功能适配
Android 10-13鼠标右键返回功能适配 文章目录 Android 10-13鼠标右键返回功能适配一、前言二、鼠标右键适配修改1、Android 10 以及更低版本2、Android11 或者更高版本三、总结1、鼠标右键返回功能修改主要代码2、标右键返回修改代码系统源码搜索3、其他 一、前言 Android 原生…...
51单片机/STM32F103/STM32F407学习1_点亮LED灯
目录: 基础知识单片机从0实现单片机GPIO介绍 参考连接: 野火霸天虎教程 https://doc.embedfire.com/products/link/zh/latest/mcu/stm32/ebf_stm32f407_batianhu_v1_v2/download/stm32f407_batianhu_v1_v2.html x.1 基础知识 x.1.1 指针中的取地址&a…...
(Transfer Learning)迁移学习在IMDB上训练情感分析模型
1. 背景 有些场景下,开始的时候数据量很小,如果我们用一个几千条数据训练一个全新的深度机器学习的文本分类模型,效果不会很好。这个时候你有两种选择,1.用传统的机器学习训练,2.利用迁移学习在一个预训练的模型上训练…...
蓝桥杯每日一题2023.11.20
题目描述 “蓝桥杯”练习系统 (lanqiao.cn) 题目分析 方法一:暴力枚举,如果说数字不在正确的位置上也就意味着这个数必须要改变,进行改变记录即可 #include<bits/stdc.h> using namespace std; const int N 2e5 10; int n, a[N], …...
【迅搜02】究竟什么是搜索引擎?正式介绍XunSearch
究竟什么是搜索引擎?正式介绍XunSearch 啥?还要单独讲一下啥是搜索引擎?不就是百度、Google嘛,这玩意天天用,还轮的到你来说? 额,好吧,虽然大家天天都在用,但是我发现&am…...
【Sql】sql server还原数据库的时候,提示:因为数据库正在使用,所以无法获得对数据库的独占访问权。
【问题描述】 sql server 还数据库的时候,提示失败。 点击左下角进度位置,可以得到详细信息: 因为数据库正在使用,所以无法获得对数据库的独占访问权。 【解决方法】 针对数据库先后执行下述语句,获得独占访问权后&a…...
【Go语言实战】(26) 分布式搜索引擎
Tangseng 基于Go语言的搜索引擎 github地址:https://github.com/CocaineCong/tangseng 详细介绍地址:https://cocainecong.github.io/tangseng 这两周我也抽空录成视频发到B站的~ 本来应该10月份就要发了,结果一鸽就鸽到现在hh…...
【理解ARM架构】不同方式点灯 | ARM架构简介 | 常见汇编指令 | C与汇编
🐱作者:一只大喵咪1201 🐱专栏:《理解ARM架构》 🔥格言:你只管努力,剩下的交给时间! 目录 🏀直接操作寄存器点亮LED灯🏀地址空间🏀ARM内部的寄存…...
JS服务端技术—Node.js知识点锦集
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/134544523 出自【进步*于辰的博客】 接触Node.js挺长时间了,工作也经常使用…...
界面控件DevExpress WPF流程图组件,完美复制Visio UI!(一)
DevExpress WPF Diagram(流程图)控件帮助用户完美复制Microsoft Visio UI,并将信息丰富且组织良好的图表、流程图和组织图轻松合并到您的下一个WPF项目中。 P.S:DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至…...
为什么选择B+树作为数据库索引结构?
背景 首先,来谈谈B树。为什么要使用B树?我们需要明白以下两个事实: 【事实1】 不同容量的存储器,访问速度差异悬殊。以磁盘和内存为例,访问磁盘的时间大概是ms级的,访问内存的时间大概是ns级的。有个形象…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
