享元模式:优化对象的共享与重复利用

news2024/11/23 3:02:04

享元模式是一种结构型设计模式,它通过共享对象来最大程度地减少内存使用和对象创建的开销。本文将深入探讨享元模式的原理、结构和使用方法,并通过详细的 Java 示例代码来说明。

1. 享元模式的定义

享元模式是一种通过共享对象来有效地支持大量细粒度对象的设计模式。它通过将对象的状态划分为内部状态和外部状态,将内部状态共享,从而减少系统中对象的数量,节省内存使用和对象创建的开销。

2. 享元模式的结构

享元模式包含以下几个核心角色:

  • 享元工厂(FlyweightFactory):享元工厂负责创建和管理享元对象。它维护一个享元池(Flyweight Pool),用于存储共享的享元对象,并根据客户端的请求返回相应的享元对象。
  • 抽象享元(Flyweight):抽象享元是享元对象的接口,定义了享元对象的公共方法。通过这些方法,可以设置和获取享元对象的外部状态。
  • 具体享元(ConcreteFlyweight):具体享元是抽象享元的实现类,实现了抽象享元定义的方法。具体享元对象中存储了享元对象的内部状态,并根据外部状态进行操作。
  • 外部状态(UnsharedConcreteFlyweight):外部状态是不可共享的状态,它随着客户端的请求而变化,不能被共享的部分。

下图展示了享元模式的结构:

3. 享元模式的工作原理

享元模式的工作原理可以简述如下:

  1. 定义享元工厂类,负责创建和管理享元对象。享元工厂类维护一个享元池,用于存储共享的享元对象。
  2. 定义抽象享元类,定义享元对象的公共方法。通过这些方法,可以设置和获取享元对象的外部状态。
  3. 定义具体享元类,实现抽象享元类定义的方法。具体享元类中存储了享元对象的内部状态,并根据外部状态进行操作。
  4. 在客户端中,通过享元工厂类获取享元对象,并设置其外部状态。客户端可以多次获取相同的享元对象,从而实现对象的共享和重复利用。

4. Java 示例代码

下面通过一个简单的 Java 示例代码来演示享元模式的使用。

首先,我们定义抽象享元类 Flyweight,定义了享元对象的公共方法:

public interface Flyweight {
    void operation(UnsharedConcreteFlyweight state);
}

然后,我们定义具体享元类 ConcreteFlyweight,实现抽象享元类定义的方法:

public class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation(UnsharedConcreteFlyweight state) {
        System.out.println("具体享元对象:" + intrinsicState);
        System.out.println("外部状态:" + state.getExternalState());
    }
}

接下来,我们定义外部状态类 UnsharedConcreteFlyweight,表示不可共享的外部状态:

public class UnsharedConcreteFlyweight {
    private String externalState;

    public UnsharedConcreteFlyweight(String externalState) {
        this.externalState = externalState;
    }

    public String getExternalState() {
        return externalState;
    }
}

最后,我们在客户端中使用享元模式,通过享元工厂类获取享元对象,并设置其外部状态:

public class Client {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        Flyweight flyweight1 = factory.getFlyweight("A");
        Flyweight flyweight2 = factory.getFlyweight("A");
        Flyweight flyweight3 = factory.getFlyweight("B");

        UnsharedConcreteFlyweight externalState = new UnsharedConcreteFlyweight("External State");

        flyweight1.operation(externalState);
        flyweight2.operation(externalState);
        flyweight3.operation(externalState);
    }
}

输出结果为:

具体享元对象:A
外部状态:External State
具体享元对象:A
外部状态:External State
具体享元对象:B
外部状态:External State

从输出结果可以看出,通过享元模式,我们成功地共享和重复利用了相同的享元对象,从而减少了内存使用和对象创建的开销。

5. 享元模式的优点和适用场景

享元模式具有以下优点:

  • 减少内存使用:享元模式通过共享对象,减少了系统中对象的数量,从而减少了内存使用。
  • 减少对象创建开销:享元模式通过共享现有对象,避免了频繁创建新对象的开销,提高了系统的性能。
  • 提高系统性能:享元模式通过共享和重复利用对象,减少了系统的负载,提高了系统的性能。
  • 灵活性增加:享元模式允许对象的内部状态和外部状态分离,使得系统更加灵活。

享元模式适用于以下场景:

  • 需要创建大量相似对象的场景,且这些对象的内部状态可以共享。
  • 需要频繁创建对象,且创建对象的开销较大。
  • 需要缓存对象的场景,以提高系统的性能。

6. 总结

享元模式是一种通过共享对象来优化内存使用和对象创建开销的设计模式。通过将对象的状态划分为内部状态和外部状态,并共享内部状态,享元模式可以减少系统中对象的数量,节省内存使用和对象创建的开销。享元模式适用于需要频繁创建相似对象、缓存对象以提高性能的场景。

公众号请关注"果酱桑", 一起学习,一起进步!

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

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

相关文章

简单的聊一聊如何用CSS制作一个专业的头部页眉(Headers)

一个吸引人的网页页眉对于给访问者留下良好的第一印象至关重要。一个设计精良的页眉不仅能够吸引注意力,还能为整个网站设定基调。借助CSS,创建现代化和视觉吸引力的网页页眉比以往任何时候都更加容易。 在本文中,我们将探索一些基本的技巧和…

虹科分享 | 如何基于IO-Link wireless方案实现工厂数据采集和状态监测

数据和数字化是工业4.0变革的关键驱动因素。从整个工厂的传感器获取数据,除了优化制造计划和流程外,还能实现强大的分析和决策。目前,基于数据的应用正在催生更多智能解决方案,以提高制造业的灵活性和敏捷性,进而提高效…

【unity细节】GameObject.Find和 transform.Find 核心区别

👨‍💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:unity细节和bug ⭐Find找子对象的子对象,GameObject.Find 和 transform.Find的区别 ⭐ 文章目录 …

jni编程(windows+JDK11+clion)

JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。 一、java代码 package org.example;public class Main {static {System.load("");}public static void main(String[] args) {Syste…

CMU 15-445 -- SortingAggregations - 08

CMU 15-445 -- Sorting&Aggregations - 08 引言Sorting为什么需要排序AlgorithmsExternal Merge Sort2-Way External Merge SortGeneral External Merge Sort实例:Sort 108 pages file with 5 buffer pages:N 108, B 5 Using B Trees Aggregations…

JavaScript--修改 HTML 元素

这些是一些用于修改 HTML 元素的常见方法&#xff1a; 1、document.createElement(element)&#xff1a;创建 HTML 元素节点。可以使用这个方法创建一个新的 HTML 元素&#xff0c; 例如 document.createElement(div) 将创建一个 <div> 元素节点。 2、document.createA…

freemarker学习

一、Freemarker引入 二、环境搭建和测试 pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/m…

PyTorch: nn网络层-卷积层

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/dive-into-AI 】或者公众号【AIShareLab】回复 pytorch教程 也可获取。 文章目录 nn网络层-卷积层1D/2D/3D 卷积一维卷积二维卷积三维卷积 二维卷积&#xff1a;nn.Conv2d()卷积尺寸计算简化版卷积尺…

华为路由器如何通过Console口进行基本配置

华为HCIA试听课程&#xff1a;不会传输层协议&#xff0c;HCIA都考不过https://mp.weixin.qq.com/s/oKAL8GvdrcHEb5O_8bEZZQ 思科CCNA试听课程&#xff1a;适合初学者&#xff1a;VLAN原理与配置https://mp.weixin.qq.com/s/toIJg1EVFImalrwzbTONTQ 组网图形 组网需求 通过Cons…

【2023,学点儿新Java-31】测试:整型和浮点型变量的使用 | 附:计算机存储单位(转换关系)| 企业真题:为什么0.1+0.2不等于0.3

前情提要&#xff1a; 【2023&#xff0c;学点儿新Java-30】变量的基本使用&#xff1a;变量的意义 | 变量的构成要素 | Java中变量的数据类型、变量的使用 | 附&#xff1a;Java中变量的作用域 | 数据类型、变量名和变量值哪个最重要&#xff1f;【2023&#xff0c;学点儿新J…

vue中使用v-for实现两次嵌套循环,判断某子元素是否显示,进行复杂表单校验

一、需求场景&#xff1a; 有以下一个使用场景&#xff0c;名称111、名称222、名称333&#xff0c;是放在一个大数组里的&#xff0c;然后通过第一层for循环显示出来的。名称333数组里又包含自己的子数组&#xff0c;子数组再通过第二次for循环展示出来。当我们选择发放方式的…

基于Javaweb实现ATM机系统开发实战(七)用户密码修改

接下来我们完成密码修改的功能&#xff0c;还是老规矩先看前端界面&#xff1a;这里我们先把需要的变量进行修改&#xff0c;然后把卡号变成不可修改&#xff1a; <% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-…

深度挖掘文物价值,VR博物馆讲好文物故事

文物不言&#xff0c;自有春秋。丝绸、字画、瓷器、古玩等&#xff0c;铺陈的是传奇&#xff0c;激荡的是灵魂。历史文物珍贵的莫过于其历史与文化的价值&#xff0c;倘若不能被更多的人欣赏、研究、传承&#xff0c;那么这些文物就很难实现“价值外溢”。 单纯的去读历史课本&…

分层解耦-三层架构

三层架构 在上篇文章的案例中写文章-CSDN创作中心 的Controller类承担了对于数据操作&#xff08;访问&#xff09;、对于对于数据的逻辑处理、以及接受请求响应数据的工作&#xff0c;对于类似的小项目来说冗杂程度还可以接收&#xff0c;但是如果项目更加复杂&#xff0c;就…

QT使用同一按钮实现打开/关闭新窗口

QT使用同一按钮实现【打开/关闭】新窗口&#xff0c;实现方案如下&#xff1a; 使用一个全局状态变量记录窗口打开状态通过该状态实现新窗口的show和close 实现代码如下&#xff1a; #include "mainwindow.h" #include "ui_mainwindow.h" #include "…

怎么用PDF24 Tools工具在线进行PDF文件合并

PDF文件是经常会被用到&#xff0c;它在我们的日常生活和工作中扮演着重要的角色。PDF文件合并是将多个PDF文件合并为单个文件&#xff0c;这个过程通常是为了方便管理多个PDF文件&#xff0c;或者将多个PDF文件合并为一个整体以便于共享或打印。既然如此&#xff0c;如何快速合…

达梦sql执行计划、HINT、索引简单应用

目录 收集统计信息. 3 1. 通过DBMS_STATS包中的方法. 3 2、删除指定表的统计信息. 3 执行计划. 3 常用执行计划操作符. 4 统计指定sql执行号的所有操作符的执行时间. 5 HINT 5 并行操作&#xff1a;. 6 查询计划重用、结果集重用. 7 示例. 8 1、收集统计信息&#x…

Comparable/Comparator

现在有一个自定义学生的学生类,里面有name属性,和age属性,我们如何去比较大小? class Student{public String name;public int age;public Student(String name, int age) {this.name name;this.age age;}Overridepublic String toString() {return "Student{" &…

路径规划算法:基于广义正态分布优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于广义正态分布优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于广义正态分布优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用…

关于博客更新的二三事

原文链接&#xff1a;关于博客更新的二三事 前言 很显然&#xff0c;正如大家所见到的&#xff0c;这一版本主题v4.7.0进行了大量的删减工作。可能正如 “大道至简” 吧&#xff0c;相比于前一版本 v3.7.1 &#xff0c;个人认为可能有点花哨&#xff08;仅个人认为&#xff09…