当前位置: 首页 > news >正文

设计模式——享元模式

享元模式(Flyweight Pattern)是一种结构型设计模式,它的主要目的是通过共享已存在的对象来大幅度减少需要创建的对象数量,从而降低系统内存消耗和提高性能。它通过将对象的状态划分为内部状态(Intrinsic State)和外部状态(Extrinsic State),仅共享具有相同内部状态的对象。

原理

  • 抽象享元类(Flyweight Interface): 定义了所有具体享元类的公共接口,通过这个接口客户端可以访问内在状态。
  • 具体享元类(Concrete Flyweight): 实现抽象享元类,存储并提供内部状态共享的具体实现。
  • 享元工厂(Flyweight Factory): 负责创建和管理享元对象,并确保正确地重用现有的享元对象。当请求一个新对象时,如果该对象已经存在,则返回已有的实例;否则,才创建一个新的实例。

Java代码示例

// 抽象享元类
public interface Shape {void draw(int x, int y);
}// 具体享元类:圆形
public class Circle implements Shape {private String color; // 外部状态,不共享// 内部状态,被多个对象共享private static Map<String, Circle> circlePool = new HashMap<>();private Circle(String color) {this.color = color;}// 由享元工厂负责调用此方法以复用已有对象或创建新的对象public static Circle getCircle(String color) {if (!circlePool.containsKey(color)) {circlePool.put(color, new Circle(color));}return circlePool.get(color);}@Overridepublic void draw(int x, int y) {System.out.println("Drawing a circle at (" + x + ", " + y + ") with color: " + color);}
}// 享元工厂
public class ShapeFactory {public static Shape getShape(String shapeType, String color) {if ("circle".equals(shapeType)) {return Circle.getCircle(color);} else {// 其他类型的形状处理...throw new UnsupportedOperationException("Unsupported shape type");}}
}// 客户端
public class Client {public static void main(String[] args) {Shape circle1 = ShapeFactory.getShape("circle", "red");circle1.draw(10, 10);Shape circle2 = ShapeFactory.getShape("circle", "blue");circle2.draw(50, 50);// 如果颜色“red”已经创建过,则circle3会复用之前的红色圆对象Shape circle3 = ShapeFactory.getShape("circle", "red");circle3.draw(100, 100);}
}

想象你正在运营一家制作个性化T恤衫的公司,每种颜色的T恤都是单独的一件衣服。为了节约成本,你会把每种颜色的T恤看作是共享资源,即每个颜色只准备一件基础T恤。当客户订购某种颜色的T恤时,只要仓库中有对应颜色的基础T恤,就直接使用这件基础T恤进行个性化的打印,而不是每次都生产一件全新的T恤。这就是享元模式的思想,在这里,颜色就是内部状态,而T恤上的文字或图案则是外部状态。

应用场景

  • 在图形用户界面中,绘制大量的相似对象,如字体、图标等,它们的大部分属性是相同的,只有少数属性因位置或大小不同而变化。
  • 大规模游戏场景中的大量小物件,比如森林里的树叶,可以通过共享纹理资源来节省内存。

适用性

  • 系统中存在大量相似对象并且这些对象的大部分状态都可以外部化时。
  • 对象的大多数状态都可以变为不可变的,并且可以合理划分内部状态和外部状态。
  • 需要大幅度减少创建对象的数量,以节省内存和提高性能。

相关文章:

设计模式——享元模式

享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;它的主要目的是通过共享已存在的对象来大幅度减少需要创建的对象数量&#xff0c;从而降低系统内存消耗和提高性能。它通过将对象的状态划分为内部状态&#xff08;Intrinsic State&#xf…...

【Python机器学习】分类器的不确定估计——决策函数

scikit-learn接口的分类器能够给出预测的不确定度估计&#xff0c;一般来说&#xff0c;分类器会预测一个测试点属于哪个类别&#xff0c;还包括它对这个预测的置信程度。 scikit-learn中有两个函数可以用于获取分类器的不确定度估计&#xff1a;decidion_function和predict_pr…...

云原生周刊:K8sGPT 加入 CNCF | 2024.1.8

开源项目推荐 VolSync VolSync 使用 rsync 或 rclone 在集群之间异步复制 Kubernetes 持久卷。它还支持通过 Restic 创建持久卷的备份。 KubeClarity KubeClarity 是一种用于检测和管理软件物料清单 (SBOM) 以及容器映像和文件系统漏洞的工具。它扫描运行时 K8s 集群和 CI/…...

LightGBM原理和调参

背景知识 LightGBM(Light Gradient Boosting Machine)是一个实现GBDT算法的框架&#xff0c;具有支持高效率的并行训练、更快的训练速度、更低的内存消耗、更好的准确率、支持分布式可以处理海量数据等优点。 普通的GBDT算法不支持用mini-batch的方式训练&#xff0c;在每一次…...

ROS无人机开发常见错误

飞控部分 一、解锁时飞控不闪红灯&#xff0c;无任何反应&#xff0c;地面站也无报错 解决办法&#xff1a; 打开地面站的遥控器一栏 首先检查右下角Channel Monitor是否有识别出遥控各通道的值&#xff0c;如果没有&#xff0c;检查遥控器是否打开&#xff0c;遥控器和接收…...

Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为AVI视频格式(C#)

Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为视频格式&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的图像转换为OpenCV的图像的技术背景在NEOAPI SDK里实现相机图像转换为视频格式 工业相机通过OpenCV实现相机图像转换为视频格式的优…...

第一次面试总结 - 迈瑞医疗 - 软件测试

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对专栏 “本人真实面经” 很感兴趣o (ˉ▽ˉ&#xff1b;) 专栏 —— 本人真实面经&#xff0c;更多真实面试经验&#xff0c;中大厂面试总结等您挖掘 注&#xff1a;此次面经全靠小嘴八八&#xff0c;没…...

利用Qt输出XML文件

使用Qt输出xml文件 void PixelConversionLibrary::generateXML() {QFile file("D:/TEST.xml");//创建xml文件if (!file.open(QIODevice::WriteOnly | QIODevice::Text))//以只写方式&#xff0c;文本模式打开文件{qDebug() << "generateXML:Failed to op…...

OpenWrt智能路由器Wan PPPoE拨号配置方法

OpenWrt智能路由器的wan PPPoE拨号配置方法和我们常见的不太一样, 需要先找到wan网卡,然后将协议切换为 PPPoE然后才能看到输入上网账号和密码的地方. 首先登录路由器 http://openwrt.lan/ 然后找到 Network --> Interfaces 这里会显示你当前的路由器的所有接口, 选择 …...

(十一)IIC总线-AT24C02-EEPROM

文章目录 IIC总线篇AT24C02-EEPROM篇主要特性引脚说明AT24Cxx用几位数据地址随机寻址的(存储器组织)AT24C02设备操作AT24CXX设备寻址EEPROM写操作的种类EEPROM读操作的种类实现单字节写实现任意读读写应用 IIC总线篇 前面介绍过了&#xff0c;请参考 (十)IIC总线-PCF8591-ADC/…...

现在做电商还有发展空间吗?哪个平台的盈利比较大?

我是电商珠珠 对于部分人来说&#xff0c;实体店的投入太大&#xff0c;一上来就是十几w&#xff0c;有时候还看不到结果。 所以有的人就瞄准了电商这个圈子&#xff0c;做线上平台。 大家都知道&#xff0c;近年来直播电商很火&#xff0c;所以很多商家都会去找达人带货&am…...

多节点 docker 部署 elastic 集群

参考 Install Elasticsearch with Docker Images 环境 docker # docker version Client: Docker Engine - CommunityVersion: 24.0.7API version: 1.43Go version: go1.20.10Git commit: afdd53bBuilt: Thu Oct 26 09:08:01 202…...

2023年全国职业院校技能大赛软件测试赛题—单元测试卷⑨

单元测试 一、任务要求 题目1&#xff1a;根据下列流程图编写程序实现相应分析处理并显示结果。返回文字“xa*a*b的值&#xff1a;”和x的值&#xff1b;返回文字“xa-b的值&#xff1a;”和x的值&#xff1b;返回文字“xab的值&#xff1a;”和x的值。其中变量a、b均须为整型…...

C++核心编程——文件操作

本专栏记录C学习过程包括C基础以及数据结构和算法&#xff0c;其中第一部分计划时间一个月&#xff0c;主要跟着黑马视频教程&#xff0c;学习路线如下&#xff0c;不定时更新&#xff0c;欢迎关注。 当前章节处于&#xff1a; ---------第1阶段-C基础入门 ---------第2阶段实战…...

【REST2SQL】05 GO 操作 达梦 数据库

【REST2SQL】01RDB关系型数据库REST初设计 【REST2SQL】02 GO连接Oracle数据库 【REST2SQL】03 GO读取JSON文件 【REST2SQL】04 REST2SQL第一版Oracle版实现 信创要求用国产数据库&#xff0c;刚好有项目用的达梦&#xff0c;研究一下go如何操作达梦数据库 1 准备工作 1.1 安…...

GitLab 502 Whoops, GitLab is taking too much time to respond. 解决

1、先通过gitlab-ctl restart进行重启&#xff0c;2分钟后看是否可以正常访问&#xff0c;为什么要2分钟&#xff0c;因为gitlab启动会有很多配套的服务启动&#xff0c;包括postgresql等 2、如果上面不行&#xff0c;再看gitlab日志&#xff0c;通过gitlab-ctl tail命令查看&…...

vi ~/.bashrc 后如何编辑并退出

在使用 vi 编辑器打开 ~/.bashrc 文件后&#xff0c;可以按照以下步骤编辑并保存退出&#xff1a; vi ~/.bashrc 按 i 进入插入模式&#xff1a; 在 vi 编辑器中&#xff0c;按 i 键将进入插入模式。在插入模式中&#xff0c;您可以编辑文本。 编辑文件&#xff1a; 在插入模…...

KVM Vcpu概述

KVM Vcpu概述 Intel VTSMP系统CPU过载使用CPU模型CPU绑定和亲和性CPU优化 Intel VT Intel的硬件虚拟化技术大致分为3类&#xff1a; 1、VT-x技术&#xff1a;是指Intel处理器中的一些虚拟化技术支持&#xff0c;包括CPU中最基础的VMX技术&#xff0c;也包括内存虚拟化的硬件支…...

linux服务器ftp部署

1、ftp服务安装 # 检查是否安装 1、查询安装列表 sudo systemctl list-unit-files --typeservice | grep ftp 2、查询ftp服务状态 sudo service vsftpd status 或者 sudo systemctl status vsftpd # yum安装&#xff0c;一般yum仓库都有ftp安装包 sudo yum install vsftpd # 启…...

NSIS 安装windows 安装包(包括QT和MFC)

NSIS&#xff08;Nullsoft Scriptable Install System&#xff09;是一个开源的 Windows 系统下安装程序制作程序。它提供了安装、卸载、系统设置、文件解压缩等功能。 基本概念 区段 是对应某种安装/卸载选项的处理逻辑&#xff0c;该段代码仅当用户选择相应的选项才被执行…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...