Java设计模式:享元模式实现高效对象共享与内存优化(十一)

码到三十五 : 个人主页


目录

    • 一、引言
    • 二、享元设计模式的概念
      • 1. 对象状态的划分
      • 2. 共享机制
    • 三、享元设计模式的组成
    • 四、享元设计模式的工作原理
    • 五、享元模式的使用
    • 六、享元设计模式的优点和适用场景
    • 结语

[参见]:

Java设计模式:核心概述(一)

Java设计模式:单例模式之六种实现方式详解(二)

Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)

Java设计模式:建造者模式之经典与流式的三种实现(四)

Java设计模式:适配器模式的三种形式(五)

Java设计模式:深入装饰器模式的三种写法(六)

Java设计模式:组合模式之透明与安全的两种实现(七)

Java设计模式:代理模式的静态和动态之分(八)

Java设计模式:外观模式之优雅门面(九)

Java设计模式:组合优于继承化身之桥接模式(十)

一、引言

设计模式是一种用于解决在特定上下文中经常出现的问题的优秀解决方案。它们为开发人员提供了一种通用的设计语言,有助于创建灵活且可维护的代码。享元设计模式(Flyweight Pattern)是结构型模式之一,它通过共享对象来减少系统中对象的数量,从而降低系统资源消耗,提高系统性能。

二、享元设计模式的概念

享元设计模式(Flyweight Pattern)是众多设计模式中的一种,它专注于解决由于创建大量相似对象而导致的系统资源消耗过高的问题。这一模式的核心思想是“共享”,即通过共享尽可能多的对象来减少系统中对象的总数,进而降低内存占用和提高系统性能。

1. 对象状态的划分

在享元模式中,一个关键的概念是将对象的状态划分为两部分:内在状态(Intrinsic State)和外在状态(Extrinsic State)。

  • 内在状态:这是对象内部固有的、不会随环境改变而变化的属性。内在状态通常是可以被共享的,因为它不会因外在条件的不同而有所区别。例如,在一个字符渲染系统中,字符的字体、大小等属性就可以被视为内在状态,因为不论在什么上下文中,相同字体和大小的字符都可以被复用。

  • 外在状态:这是对象在特定上下文中才有的、会随着环境改变而变化的属性。外在状态是不能被共享的,因为它依赖于对象所处的具体环境和上下文。继续以字符渲染为例,字符的位置、颜色等可能因用户交互或页面布局的不同而变化,因此这些属性被视为外在状态。

2. 共享机制

享元模式通过实现一个享元工厂(Flyweight Factory)来管理对象的创建和共享。享元工厂会维护一个已创建享元对象的缓存(通常是一个哈希表或其他快速查找数据结构),并根据请求的类型(通常由内在状态决定)来返回相应的对象实例。如果请求的类型在缓存中已存在,则直接返回该实例;如果不存在,则创建一个新的享元对象,将其添加到缓存中,并返回给请求者。

  1. 提升性能与资源利用率
    通过上述共享机制,享元模式能够显著减少系统中相似对象的数量,从而降低内存占用。同时,由于避免了不必要的对象创建和销毁操作,系统的整体性能也会得到提升。这在处理大量相似对象时尤为重要,如文本编辑器中的字符渲染、图形界面中的图形元素绘制等场景。

综上所述,享元设计模式是一种通过共享对象来优化系统资源消耗和提高性能的设计方案。它通过将对象状态划分为内在状态和外在状态,并利用享元工厂来管理对象的创建和共享,从而实现了对相似对象的高效处理。

三、享元设计模式的组成

在这里插入图片描述

  1. Flyweight(享元):这是享元对象,它封装了可以被共享的状态,并且可以被高效地复用。

  2. FlyweightFactory(享元工厂):这个工厂负责创建和管理享元对象。它通常会缓存已创建的享元对象,并在请求相同类型的享元时返回已有的实例。

  3. Client(客户端):客户端代码使用享元工厂来获取享元对象,并在需要时将其外在状态传递给享元。

四、享元设计模式的工作原理

享元模式的核心思想是“共享”。当系统中需要创建大量相似对象时,享元模式通过以下步骤来优化对象的创建和使用:

  1. 提取共享状态:首先,识别出对象中可以共享的状态,并将其封装在享元类中。

  2. 分离变化状态:将不能共享或随上下文变化的状态从享元类中分离出来,作为外在状态。

  3. 创建享元工厂:实现一个享元工厂来管理享元对象的创建和缓存。当客户端请求一个新的享元时,工厂首先检查缓存中是否已经存在相同类型的享元。如果存在,则返回该实例;否则,创建一个新的享元实例并添加到缓存中。

  4. 客户端使用:客户端代码通过享元工厂获取享元对象,并根据需要设置其外在状态。享元对象在执行操作时,会结合其内在状态和传递进来的外在状态来完成任务。

五、享元模式的使用

享元模式的实现通常涉及到一个享元类(表示要共享的对象),一个享元工厂类(负责创建和管理享元实例),以及客户端代码。下面代码展示如何使用享元模式来减少具有相同属性的对象的数量。

在这里插入图片描述

首先,定义享元类 Circle,表示一个圆形对象,其内在状态是颜色,这里假设所有圆的大小相同,因此不需要作为内在状态。

public class Circle {
    private String color; // 内在状态:颜色

    public Circle(String color) {
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    // 假设的绘制方法,这里仅打印信息
    public void draw() {
        System.out.println("绘制一个颜色为 " + color + " 的圆形");
    }
}

然后,定义享元工厂类 CircleFactory,它负责管理并缓存已经创建的 Circle 对象。

import java.util.HashMap;
import java.util.Map;

public class CircleFactory {
    private Map<String, Circle> circleMap = new HashMap<>(); // 用于缓存Circle对象的Map

    // 根据颜色获取Circle对象,如果缓存中没有则创建一个
    public Circle getCircle(String color) {
        Circle circle = circleMap.get(color);
        if (circle == null) {
            circle = new Circle(color);
            circleMap.put(color, circle); // 将新创建的Circle对象加入缓存
        }
        return circle;
    }
}

最后,编写客户端代码来使用享元工厂创建和使用享元对象。

public class FlyweightPatternDemo {
    private static final CircleFactory circleFactory = new CircleFactory();

    public static void main(String[] args) {
        // 从享元工厂获取圆形对象,并绘制它们
        Circle circle1 = circleFactory.getCircle("红色");
        circle1.draw(); // 输出:绘制一个颜色为 红色的圆形

        Circle circle2 = circleFactory.getCircle("蓝色");
        circle2.draw(); // 输出:绘制一个颜色为 蓝色的圆形

        Circle circle3 = circleFactory.getCircle("红色");
        circle3.draw(); // 输出:绘制一个颜色为 红色的圆形(注意这里是复用的circle1)

        // 验证circle1和circle3是否是同一个对象
        System.out.println(circle1 == circle3); // 输出:true
    }
}

Circle 类是享元,它的内在状态是颜色。CircleFactory 是一个享元工厂,它使用一个 HashMap 来缓存已经创建的 Circle 对象。当客户端请求一个具有特定颜色的圆形时,享元工厂首先检查缓存中是否已经有一个具有该颜色的圆形。如果有,则返回该对象;否则,创建一个新的 Circle 对象并将其添加到缓存中。通过这种方式,具有相同颜色的圆形对象实例在系统中只会被创建一次,从而减少了内存占用。

六、享元设计模式的优点和适用场景

优点

  1. 减少内存消耗:通过共享对象实例,减少了系统中对象的数量,从而降低了内存消耗。

  2. 提高性能:避免了频繁的对象创建和销毁操作,提高了系统的运行性能。

  3. 简化系统设计:享元模式有助于将对象的共享部分和变化部分分离开来,使系统设计更加清晰和灵活。

适用场景

  1. 当系统中需要处理大量相似对象时,如字符串、图形对象等。

  2. 当对象的创建成本较高,且大量对象之间存在大量重复数据时。

  3. 当需要优化系统资源消耗和提高系统性能时。

结语

享元设计模式是一种高效处理大量相似对象的设计方案。它通过共享对象实例来减少资源消耗和提高性能,适用于多种场景。在使用享元模式时,需要仔细识别对象的共享状态和变化状态,并合理设计享元类和享元工厂。通过合理运用享元模式,可以构建出更加灵活、高效和可维护的软件系统。



听说...关注下面公众号的人都变牛了,纯技术,纯干货 !

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

企业如何打造通证经济生态闭环详解(下)

一、原始账户&#xff1a;用户注册即生成【原始账户】【托管账户】。 原始账户用于存储用户所获取的通证积分&#xff0c;原始账户的公钥与私钥由用户所有&#xff0c;安全、私密、去中心化。 通过原始账户&#xff0c;用户可进行转账、收款的点对点传输&#xff0c;并可查看…

I2C协议详解

文章目录 概念工作模式 原理工作原理工作流程IIC协议的关键特点IIC通信过程 优点与缺点优点缺点 概念 IIC&#xff08;Inter-Integrated Circuit&#xff09;协议&#xff0c;也常被称为TWI&#xff08;Two-Wire Interface&#xff09;协议&#xff0c;是一种用于短距离通信的…

CyberDAO M级共识交流会·西安站圆满落幕:共筑Web3美好未来

CyberDAO M级共识交流会于2024年5月28日在西安隆重举行&#xff0c;这是一场CyberDAO精英汇聚的盛会&#xff0c;以同心共筑&#xff0c;志在必达为主题口号与DAO精英携手并进&#xff0c;共筑CyberDAO美好宏图。CyberDAO的使命是降低WEB3的门槛&#xff0c;帮助用户轻松抓住行…

STM32的时钟介绍

目录 前言1. 简介1.1 时钟是用来做什么的1.2 时钟产生的方式 2. 时钟树的组成2.1 时钟源2.1.1 内部时钟2.1.2 外部时钟 2.2 PLL锁相环2.3 SYSCLK2.4 AHB和HCLK2.5 APB和PCLK2.6 总结 3. STM32时钟的使用步骤4.我的疑问4.1 使用MSI和HSI有什么区别吗&#xff1f;4.2 MSI的频率为…

【ai】livekit:Agents 4: livekit-plugins-openai和LiveKit Plugins Silero安装与分析

先提高下性能然后本文 继续按照 上一篇【ai】livekit:Agents 3 : pythonsdk和livekit-agent的可编辑模式下的安装构建 livekit-gent的插件。pycharm 工程 配置Microsoft Defender 排除列表 livekit-plugins-openai 本地安装

window自动启动bat文件

开机自动开启远程桌面&#xff0c; WinR 执行netplwiz 命令进入设置&#xff1b;取消勾选&#xff0c;可选择所需用户&#xff0c;点击应用&#xff0c;输入远程的密码即可 开机自动开启远程桌面&#xff0c; WinR 执行netplwiz 命令进入设置&#xff1b;取消勾选&#xff0…

新书推荐—华为HCIA路由交换技术实战

新书推荐—华为HCIA路由交换技术实战 由HCIE认证讲师、技术能手、ICT大赛优秀指导教师、教学名师、国家规划教材作者联袂编撰&#xff0c;让学习不再是“硬”茬&#xff0c;而是“嗨”起来&#xff01; 《华为HCIA路由交换技术实战》 作者黄君羡组编正月十六工作室书号978-7-12…

Linux 编译器gcc/g++使用

gcc/g同理 编译器运行过程 1. 预处理&#xff08;进行宏替换) gcc -E a.c -o a.i 预处理后还是c语言 -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面 告诉gcc&#xff0c;从现在开始进行程序的翻译&#xff0c;将预处理工作做完停下 2. 编译&#x…

ETLCloud中如何执行SQL脚本

SQL脚本 在数据库管理与数据分析的广阔领域中&#xff0c;SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;脚本扮演着举足轻重的角色。作为一门专为关系型数据库设计的编程语言&#xff0c;SQL不仅能够执行数据的检索、更新、插入及删除等基…

python列表元素操作与函数应用详解

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、列表元素加一的实现方法 示例代码 二、列表生成式的简化操作 三、列表反转函数revers…

解密网络流量监控:优化IT运维的利器

引言&#xff1a; 在当今数字化时代&#xff0c;网络流量监控是维护网络稳定与业务连续性的关键。作为一名资深网络工程师&#xff0c;我将分享一些关于网络流量监控的重要知识&#xff0c;并探讨如何在IT运维中运用这一工具优化网络性能&#xff0c;确保业务的顺畅进行。 1. 网…

jquery---ajax方法示例

ajax方法 $.ajax({name:value, name:value, ... }) ajax方法有一个参数&#xff0c;一定长度的对象&#xff0c;内部指定了ajax的请求地址和格式&#xff0c;方式等等&#xff0c;它可以有以下的属性和值 示例 这里展示了一个简单的get请求图片url的实例 let data; let url…

压力测试JMeter

压力测试JMeter 1 下载JMeter1.1 测试计划1.2 JMeter Address Already in use 错误解决1.3 java 内存模型1.4 jconsole与jvisualvm1.5 优化方向1.6 Nginx动静分离 1 下载JMeter 官网地址&#xff1a;https://jmeter.apache.org/download_jmeter.cgi 运行apache-jmeter-5.6.3\…

Linux 驱动设备匹配过程

一、Linux 驱动-总线-设备模型 1、驱动分层 Linux内核需要兼容多个平台&#xff0c;不同平台的寄存器设计不同导致操作方法不同&#xff0c;故内核提出分层思想&#xff0c;抽象出与硬件无关的软件层作为核心层来管理下层驱动&#xff0c;各厂商根据自己的硬件编写驱动…

手把手从0到1教你做STM32+FreeRTOS智能家居--第10篇之ASR-PRO语音识别模块

前言 先看实验效果&#xff0c;通过ASR-PRO语音智能识别控制模块&#xff0c;来控制STM32单片机实现对应的控制功能。因为后台好多小伙伴私信问用的是什么语音模块&#xff0c;并且很少在网上看到如何使用此模块相关的文章&#xff0c;所以我将会在本篇文章详细介绍一下此模块…

国际数字影像产业园|科技与文创产品创意集市,共筑创新文化新高地

5月29日&#xff0c;为进一步增强园区与企业之间粘性&#xff0c;不断激发企业的创新活力&#xff0c;园区举办了“数媒大厦科技与文创产品创意集市活动”。本次活动由成都树莓信息技术有限公司主办&#xff0c;成都目莓商业管理有限公司、树莓科技&#xff08;成都&#xff09…

成都欣丰洪泰文化传媒有限公司助力品牌快速崛起

在当今数字化浪潮汹涌的时代&#xff0c;电商行业作为新经济的代表&#xff0c;正以其独特的魅力和无限的潜力&#xff0c;引领着商业模式的创新与变革。在这个充满机遇与挑战的领域里&#xff0c;成都欣丰洪泰文化传媒有限公司凭借其专业的电商服务能力和前瞻性的战略眼光&…

【Paddle】Inplace相关问题:反向传播、影响内存使用和性能

【Paddle】Inplace相关问题&#xff1a;反向传播、影响内存使用和性能 写在最前面inplace 的好处有哪些&#xff1f;能降低计算复杂度吗在反向传播时&#xff0c;Inplace为什么会阻碍呢&#xff1f;“计算图的完整性受损”表达有误原地操作 sin_()为什么原地操作会阻碍反向传播…

IPFoxy Tips:海外代理IP适用的8个跨境出海业务

在当今数字化时代&#xff0c;互联网已经成为商业和个人生活不可或缺的一部分。IP代理作为出海业务的神器之一&#xff0c;备受跨境出海业务人员关注。IPFoxy动态、静态纯净代理IP也根据业务需求的不同&#xff0c;分为静态住宅、动态住宅、静态IPv4、静态IPv6四种类型代理。那…

祝贺!阿里云PolarDB斩获数据库国际顶会ICDE 2024工业赛道最佳论文

5月17日消息&#xff0c;在荷兰举行的国际顶级数据库学术会议ICDE 2024上&#xff0c;阿里云斩获工业和应用赛道的“最佳论文奖”&#xff0c;这也是中国企业首次获此殊荣。阿里云PolarDB创新性地解决了数据库Serverless中跨机事务迁移的核心难题&#xff0c;将跨机迁移时间压缩…