Java特性之设计模式【享元模式】

一、享元模式

概述

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式

享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象

主要解决

在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建

何时使用

1、系统中有大量对象

2、这些对象消耗大量内存

3、这些对象的状态大部分可以外部化

4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替

5、系统不依赖于这些对象身份,这些对象是不可分辨的

优缺点

优点:

  • 大大减少对象的创建,降低系统的内存,使效率提高

缺点:

  • 提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱

1. 各个角色介绍

1.1 享元工厂(Flyweight Factory)

  • 负责创建和管理享元对象,通常包含一个池(缓存)用于存储和复用已经创建的享元对象

1.2 具体享元(Concrete Flyweight)

  • 实现了抽象享元接口,包含了内部状态和外部状态。内部状态是可以被共享的,而外部状态则由客户端传递

1.3 抽象享元(Flyweight)

  • 定义了具体享元和非共享享元的接口,通常包含了设置外部状态的方法

2. UML图

​ 我们将创建一个 Shape 接口和实现了 Shape 接口的实体类 Circle。下一步是定义工厂类 ShapeFactory

ShapeFactory 有一个 CircleHashMap,其中键名为 Circle 对象的颜色。无论何时接收到请求,都会创建一个特定颜色的圆。ShapeFactory 检查它的 HashMap 中的 Circle 对象,如果找到 Circle 对象,则返回该对象,否则将创建一个存储在 HashMap 中以备后续使用的新对象,并把该对象返回到客户端

Main 类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(red / green / blue/ black / white),以便获取它所需对象的颜色

在这里插入图片描述

3. 具体例子和代码

角色分配

  • Shape:形状接口
    • Circle:实现形状接口的圆形类
  • ShapeFactory:形状工厂

3.1 抽象形状及其实现类

  • Shape
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 形状接口* @since 2024/3/15 16:23*/
public interface Shape {/*** 形状绘制动作*/void draw();}
  • Circle
package com.vinjcent.prototype.flyweight;import io.swagger.annotations.ApiModelProperty;/*** @author vinjcent* @description 圆形* @since 2024/3/20 20:31*/
public class Circle implements Shape {@ApiModelProperty("颜色")private String color;@ApiModelProperty("x轴")private int x;@ApiModelProperty("y轴")private int y;@ApiModelProperty("半径")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.2 形状工厂

  • ShapeFactory
package com.vinjcent.prototype.flyweight;import java.util.HashMap;
import java.util.Map;/*** @author vinjcent* @description 形状工厂* @since 2024/3/22 17:33*/
public class ShapeFactory {private static final Map<String, Shape> CIRCLE_MAP = new HashMap<>();public static Shape getCircle(String color) {// 根据color获取内存Map中的Shape对象Circle circle = (Circle) CIRCLE_MAP.get(color);// 如果不存在则创建一个Shape,并将该Shape存入缓存中if (circle == null) {circle = new Circle(color);CIRCLE_MAP.put(color, circle);System.out.println("The color of circle doesn't exist, Creating circle : " + color);}return circle;}}

3.3 测试主函数

package com.vinjcent.prototype.flyweight;/*** @author vinjcent* @description 享元模式* @since 2024/3/22 17:39*/
public class Main {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() {// 生成一个[0, 5)区间的数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);}}
  • 测试结果

在这里插入图片描述

4. 使用场景

  • 系统有大量相似对象
  • 需要缓冲池的场景

在这里插入图片描述

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

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

相关文章

ffmpeg7.0 flv支持hdr

ffmpeg7.0 flv支持hdr 自从ffmpeg6.0应用enhance rtmp支持h265/av1的flv格式后&#xff0c;7.0迎来了flv的hdr能力。本文介绍ffmpeg7.0如何支持hdr in flv。 如果对enhance rtmp如何支持h265不了解&#xff0c;推荐详解Enhanced-RTMP支持H.265 1. enhance rtmp关于hdr 文档…

简述前后端分离架构案例

Hello , 这里是小恒不会java 。今晚1点写写关于RESTful接口的使用案例&#xff0c;本文会通过django原生js前后端分离的案例简单讲解。本文带你认识一下简化版的前后端分离架构 代码 本文案例代码在GitHub上 https://github.com/lmliheng/fontend前后端分离 先说说什么是前后…

Go中如何将io.Writer转换成字符串(将两个管道连接的exec.Command输出的标准输出获取成字符串)

假设我们需要在Go中运行下面的命令&#xff1a; PS -A | grep wget这里需要写成两个exec.Command&#xff0c;如下&#xff0c;第一个命令为cmd&#xff0c;第二个为cmd2&#xff1a; cmd : exec.Command("PS", "-A") cmd2 : exec.Command("grep&qu…

Leetcode 第396场周赛 问题和解法

问题 有效单词 有效单词需要满足以下几个条件&#xff1a; 至少包含3个字符。 由数字0-9和英文大小写字母组成。&#xff08;不必包含所有这类字符。&#xff09; 至少包含一个元音字母。 至少包含一个辅音字母。 给你一个字符串word。如果word是一个有效单词&#xff0c;则…

Spring扩展点(三)Spring常用内置工具类

Spring常用内置工具类 Base64UtilsFileCopyUtilsFileSystemUtilsReflectionUtilsResourceUtilsStringUtilsAopUtilsMethodInvokingBean(简洁反射调用&#xff0c;指定类的指定方法&#xff0c;将其声明为Bean即可在 afterPropertiesSet 阶段触发反射方法调用)ReflectionUtils&a…

GateWay检查接口耗时

添加gateway依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency>创建一个LogTimeGateWayFilterFactory类&#xff0c;可以不是这个名字但是后面必须是x…

【高校科研前沿】中国科学院地理资源所钟帅副研究员研究组博士生朱屹东为一作在Top期刊发文:从潜力到利用:探索西藏风能资源开发的技术路径优化布局

01 文章简介 论文名称&#xff1a;From potential to utilization: Exploring the optimal layout with the technical path of wind resource development in Tibet&#xff08;从潜力到利用:探索西藏风能资源开发的技术路径优化布局&#xff09; 文章发表期刊&#xff1a;《…

【Pytorch】2.TensorBoard的运用

什么是TensorBoard 是一个可视化和理解深度爵溪模型的工具。它可以通过显示模型结构、训练过程中的指标和图形化展示训练的效果来帮助用户更好地理解和调试他们的模型 TensorBoard的使用 安装tensorboard环境 在终端使用 conda install tensorboard通过anaconda安装 导入类Sum…

车道线检测交通信号识别车辆实时检测

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言车道线检测机器学习前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 本文先对车道线检测&交通信号识别&…

蛋白质/聚合物防污的机器学习(材料基因组计划)

前言&#xff1a;对于采用机器学习去研究聚合物的防污性能&#xff0c;以及或者其他性质。目前根据我的了解我认为最困难的点有三条&#xff1a; 其一&#xff1a;数据&#xff0c;对于将要训练的数据必须要有三点要求&#xff0c;1.数据要多&#xff0c;也就是大数据&#xff…

Retrofit使用举例, Android Gradle 知识,RxJava和接口回调,Activity与Fragmen关系

目录 Retrofit使用举例 Android Gradle 知识 1. Gradle Wrapper​编辑 2. 构建文件 3. 依赖管理

电子取证平航杯的复现

闻早起部分&#xff1a; 一、闻早起的windows10电脑 &#xff08;1&#xff09;.“闻早起”所使用的笔记本电脑使用何种加密程式&#xff1f; 1.在EFI文件中找到加密程式 &#xff08;2&#xff09; 教徒“闻早起”所使用的笔记本电脑中安装了一款还原软件&#xff0c;其版本…

寻找最佳App分发平台:小猪APP分发脱颖而出

在当今移动应用市场日益饱和的环境下&#xff0c;选择一个合适的App分发平台对于开发者来说至关重要。这不仅关系到应用能否快速触达目标用户&#xff0c;还直接影响到品牌的塑造与市场份额的争夺。本文将深入探讨几大关键因素&#xff0c;帮助开发者判断哪个App分发平台最适合…

SAP系统简介,接口的调用方式,以及各个方式的比较

SAP系统是一套企业资源规划&#xff08;ERP&#xff09;软件&#xff0c;由德国SAP公司开发。SAP的全名是“System Applications and Products in Data Processing”&#xff08;数据处理中的系统、应用与产品&#xff09;。SAP系统旨在帮助企业管理和整合公司的关键业务流程。…

Whisper、Voice Engine推出后,训练语音大模型的高质量数据去哪里找?

近期&#xff0c;OpenAI 在语音领域又带给我们惊喜&#xff0c;通过文本输入以及一段 15 秒的音频示例&#xff0c;可以生成既自然又与原声极为接近的语音。值得注意的是&#xff0c;即使是小模型&#xff0c;只需一个 15 秒的样本&#xff0c;也能创造出富有情感且逼真的声音。…

【driver4】锁,错误码,休眠唤醒,中断,虚拟内存,tasklet

文章目录 1.互斥锁和自旋锁选择&#xff1a;自旋锁&#xff08;开销少&#xff09;的自旋时间和被锁住的代码执行时间成正比关系2.linux错误码&#xff1a;64位系统内核空间最后一页地址为0xfffffffffffff000~0xffffffffffffffff&#xff0c;这段地址是被保留的&#xff0c;如果…

全球260多个国家的年通货膨胀率数据集(1960-2021年)

01、数据简介 全球年通货膨胀率是指全球范围内&#xff0c;在一年时间内&#xff0c;物价普遍上涨的比率。这种上涨可能是由于货币过度供应、需求过热、成本上升等原因导致的。通货膨胀率是衡量一个国家或地区经济状况和物价水平的重要指标&#xff0c;通常以消费者价格指数&a…

leetcode 1652.拆炸弹

这道题没有什么明确的做法&#xff0c;我们其实可以根据数组的思想来做。 一般来说是一个循环数组的话&#xff0c;我们可以用while来处理。 如果循环次数很少&#xff0c;我们可以用一种思想&#xff0c;那就是把原先的数组再复制一份放在后面&#xff0c;这样就相当于是循环…

深度学习之DCGAN

目录 须知 转置卷积 DCGAN 什么是DCGAN 生成器代码 判别器代码 补充知识 LeakyReLU&#xff08;x&#xff09; torch.nn.Dropout torch.nn.Dropout2d DCGAN完整代码 运行结果 图形显示 须知 在讲解DCGAN之前我们首先要了解转置卷积和GAN 关于GAN在这片博客中已经很…

数据结构——链表专题2

文章目录 一、返回倒数第k 个节点二、链表的回文结构三、相交链表 一、返回倒数第k 个节点 原题链接&#xff1a;返回倒数第k 个节点 利用快慢指针的方法&#xff1a;先让fast走k步&#xff0c;然后fast和slow一起走&#xff0c;直到fast为空&#xff0c;最后slow指向的结点就…