【设计模式】享元模式

devtools/2024/9/20 1:56:25/ 标签: 设计模式, 享元模式

目录

什么是享元模式

代码实现


什么是享元模式

        Java中的享元模式(Flyweight Pattern)是一种结构型设计模式,它用于减少系统中对象的数量,以节省内存和提高性能。享元模式通过共享相似对象之间的公共部分来最小化内存使用。

享元模式中,有两种类型的对象:

  1. 内部状态(Intrinsic State):是对象的共享部分,可以被多个对象共享。这些状态通常是不变的,并且不依赖于特定的上下文环境。

  2. 外部状态(Extrinsic State):是对象的非共享部分,是对象在特定上下文环境下的变化部分。外部状态需要由客户端来维护和传递。

享元模式的核心思想是将内部状态和外部状态分离。内部状态由享元对象自身管理和维护,而外部状态由客户端来维护和传递。这样可以在一定程度上减少对象的数量,节省内存空间。

享元模式通常包含以下角色:

  • 享元工厂(Flyweight Factory):负责创建和管理享元对象。它维护一个享元池(Flyweight Pool),用于存储已经创建的享元对象,并根据客户端的请求返回相应的享元对象。

  • 抽象享元(Flyweight):定义了享元对象的接口,包含了对内部状态的操作方法。通常是一个接口或抽象类。

  • 具体享元(Concrete Flyweight):实现了抽象享元接口,并为内部状态提供了具体的实现。具体享元对象可以被多个客户端共享。

享元模式的主要优点包括:

  • 减少内存使用:通过共享相似对象的公共部分,减少了系统中对象的数量,节省了内存空间。

  • 提高性能:减少了对象的数量,可以降低系统的运行时开销,提高了系统的性能。

  • 灵活性:客户端可以通过外部状态来改变享元对象的行为,而不需要修改享元对象本身。

享元模式适用于以下情况:

  • 当系统中存在大量相似对象,并且这些对象可以被共享时。

  • 当需要缓存对象以提高性能时,例如在网络请求中缓存已经请求过的数据。

        总之,享元模式是一种非常有用的设计模式,可以帮助我们减少系统中对象的数量,节省内存空间,并提高系统的性能。

代码实现

下面是一个简单的Java代码示例,演示了如何使用享元模式:      

import java.util.HashMap;
import java.util.Map;// 抽象享元接口
interface Flyweight {void operation(String externalState);
}// 具体享元类
class ConcreteFlyweight implements Flyweight {private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}@Overridepublic void operation(String externalState) {System.out.println("ConcreteFlyweight: Intrinsic State - " + intrinsicState + ", Extrinsic State - " + externalState);}
}// 享元工厂类
class FlyweightFactory {private Map<String, Flyweight> flyweights = new HashMap<>();public Flyweight getFlyweight(String key) {if (!flyweights.containsKey(key)) {flyweights.put(key, new ConcreteFlyweight(key));}return flyweights.get(key);}
}// 客户端
public class FlyweightPatternExample {public static void main(String[] args) {FlyweightFactory factory = new FlyweightFactory();// 客户端使用享元对象Flyweight flyweight1 = factory.getFlyweight("key1");flyweight1.operation("externalState1");Flyweight flyweight2 = factory.getFlyweight("key2");flyweight2.operation("externalState2");Flyweight flyweight3 = factory.getFlyweight("key1");flyweight3.operation("externalState3");// 检查是否共享了相同的对象System.out.println("Is flyweight1 the same object as flyweight3? " + (flyweight1 == flyweight3));}
}

        在这个示例中,Flyweight是享元接口,定义了享元对象的操作方法。ConcreteFlyweight是具体享元类,实现了抽象享元接口,并为内部状态提供了具体的实现。FlyweightFactory是享元工厂类,负责创建和管理享元对象。客户端通过工厂类获取享元对象,并传递外部状态给享元对象进行操作。

        在客户端代码中,我们创建了几个享元对象,并为每个对象传递了不同的外部状态。我们还通过工厂类获取了相同的享元对象,并检查它们是否共享了相同的对象。

        非常的实用,喜欢的小伙伴可以动动你们发财的小手,给博主一个小小的点赞或者关注,就是对博主最大的鼓励,爱你们哦~~


http://www.ppmy.cn/devtools/15889.html

相关文章

react之组件与JSX

第一章 - 描述用户界面 概述&#xff1a;React是一个用于构建用户界面&#xff08;UI&#xff09;的JavaScript库&#xff0c;用户界面由按钮&#xff0c;文本和图像等小单元内容构建而成。React帮助你把它们组合成可重用&#xff0c;可嵌套的组件。从web端网站到移动端应用&a…

Flink容错机制

Flink的容错机制是一个复杂而精细的系统&#xff0c;旨在确保在分布式流处理过程中&#xff0c;即使在发生故障的情况下&#xff0c;也能保持数据的一致性和计算的正确性。以下是对Flink容错机制的详细阐述&#xff1a; 首先&#xff0c;Flink的容错机制建立在状态一致性的基础…

ATECLOUD测试系统如何检测电机驱动模块

电机驱动模块是驱动电机的电路模块&#xff0c;通过将电源提供的电能转化为电机所需的电能&#xff0c;来控制电机的启停、转速和旋转方向等。为了保证电机可以正常运行&#xff0c;需要对电机模块进行各项指标检测&#xff0c;评估电机驱动模块的性能。 西安某军工方向科技公司…

牛客NC209 最短无序连续子数组【中等 数组,双指针 C++/Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/d17f4abd1d114617b51e951027be312e 思路 解题思路 1、方法1&#xff0c;排序对比&#xff1a;将数组按升序排序&#xff0c;然后与原数组对照&#xff0c;从哪里开始变化到哪里结束变化的数组就是答案。 2、 方…

使用uni-app开发app时遇到mqtt.js不可用的问题

使用uni-app开发app时遇到mqtt.js不可用的问题 1 问题背景 基于 Vue3 版本创建了 uni-app 项目用于开发微信小程序&#xff0c;项目中用到了 mqtt.js&#xff08;v4.1.0&#xff09;&#xff0c;编译为微信小程序能够正常运行&#xff0c;但是编译为 APP 后&#xff0c;控制台…

【Java EE】文件内容的读写——数据流

目录 1.InputStream概述 1.1方法 2.FileInputStream概述 2.1构造方法 2.2代码示例 2.3.利用Scanner进行字符读取 3.OutputStream概述 3.1方法 3.2利用OutputStreamWriter进行字符写入 3.3利用PrintWriter找到我们熟悉的方法 1.InputStream概述 1.1方法 修饰符及返回…

3.8设计模式——State 状态模式(行为型)

意图 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。 结构 Context&#xff08;上下文&#xff09;定义客户感兴趣的接口&#xff1b;维护一个ConcreteState子类的实例&#xff0c;这个实例定义当前状态。State&#xff08;状态&#xff09;定义…

综合练习

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 下面我们通过一些实战练习加深对存储过程和函数的认识 以 scott 用户下 emp 数据表为基础&#xff0c;创建如下过程 (1)以部门编号为输入参数&#xff0c;查询该部门的平均…

浅理解vue2中的模板编译

vue组件实例在初始化完成各种状态数据后&#xff0c;会触发vm.$mount()方法来进行模板编译阶段&#xff0c;有两种触发方式 // 方法一&#xff1a;主动触发 new Vue({ el: #app }) if (vm.$options.el) {vm.$mount(vm.$options.el); }// 方法二&#xff1a;手动调用 new Vue()…

2024深圳杯C题的8页思路分析+所有代码可执行+参考文献+持续更新参考论文(已经更新了代码与图像)

比赛题目的完整版思路可执行代码数据参考论文都会在第一时间更新上传的&#xff0c;大家可以参考我往期的资料&#xff0c;所有的资料数据以及到最后更新的参考论文都是一次付费后续免费的。注意&#xff1a;&#xff08;建议先下单占坑&#xff0c;因为随着后续我们更新资料数…

《QT实用小工具·四十二》圆形发光图像

1、概述 源码放在文章末尾 该项目实现了图像的发光效果&#xff0c;特别适合做头像&#xff0c;项目demo演示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; import QtQuick 2.7 import QtGraphicalEffects 1.12Item {id: rootwidth: 80height: 80property int ra…

Docker中Kafka容器创建/更新Topic支持多分区

前提 自行通过docker部署好kafka&#xff0c;并启动相关容器。 假设Topic为http_capture。 #docker-kafka kafka_dir/opt/docker/kafka/build sudo rm -rf ${kafka_dir}/* cat > ${kafka_dir}/docker-compose.yml <<EOF version: "3.3" services:zookeepe…

【Vue 异步更新和 $nextTick】

文章目录 异步更新机制$nextTick 方法 异步更新机制以及 $nextTick 方法都与 Vue 的响应式系统密切相关&#xff0c;对于开发高效、流畅的应用至关重要。 异步更新机制 Vue 的数据更新是异步执行的。修改 Vue 实例的数据时&#xff0c;Vue 并不会立即更新 DOM。它将数据变更放…

tiktok中的视频怎么无水印下载

在当今数字化时代&#xff0c;TikTok已经成为了年轻人们展示自我的舞台&#xff0c;无数有趣、创意的视频在这个平台上涌现。许多人想要下载TikTok上的视频时常面临一个难题&#xff1a;水印。水印是指视频上方显示的TikTok标志&#xff0c;它在一定程度上限制了用户下载视频并…

vLLM:由伯克利大学LMSYS组织开源的大语言模型高速推理框架-显著提高了大型语言模型(LLM)的服务效率

vLLM是一个由伯克利大学LMSYS组织开源的大语言模型高速推理框架,旨在提升实时场景下语言模型服务的吞吐与内存使用效率134。它是一个快速且易于使用的库,能够与HuggingFace无缝集成134。vLLM的核心是PagedAttention算法,这是一种新颖的注意力算法,通过引入操作系统的虚拟内…

基于享元模式实现连接池

享元模式 结构 享元&#xff08;Flyweight &#xff09;模式中存在以下两种状态&#xff1a; 1. 内部状态&#xff0c;即不会随着环境的改变而改变的可共享部分。 2. 外部状态&#xff0c;指随环境改变而改变的不可以共享的部分。享元模式的实现要领就是区分应用中的这两 种…

一线实战,一次底层超融合故障导致的Oracle异常恢复

背景概述 某客户数据由于底层超融合故障导致数据库产生有大量的坏块&#xff0c;最终导致数据库宕机&#xff0c;通过数据抢救&#xff0c;恢复了全部的数据。下面是详细的故障分析诊断过程&#xff0c;以及详细的解决方案描述&#xff1a; 故障现象 数据库宕机之后&#xff0c…

Vue3页面的执行过程

在 Vue 3 中&#xff0c;一个普通的页面的执行过程可以分为以下几个环节&#xff1a; 创建 Vue 应用程序实例&#xff08;createApp&#xff09;&#xff1a; 使用 createApp 函数创建一个 Vue 根实例。配置根实例--该函数接收一个配置对象作为参数&#xff0c;其中的配置项可包…

Golang | Leetcode Golang题解之第40题组合总和II

题目&#xff1a; 题解&#xff1a; func combinationSum2(candidates []int, target int) (ans [][]int) {sort.Ints(candidates)var freq [][2]intfor _, num : range candidates {if freq nil || num ! freq[len(freq)-1][0] {freq append(freq, [2]int{num, 1})} else {…