Java中享元模式是什么/享元模式有什么用,编程如何实现,哪里用到了享元模式

news2024/11/18 16:22:43

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用!

5.8 享元模式

5.8.1 概述

运用共享技术来有效地支持大量细粒度对象的复用,通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象的开销,从而提高系统资源的利用率

5.8.2 结构

5.8.2.1 状态

  • 内部状态,即不会随着环境的改变而改变的可共享部分
  • 外部状态,即随环境改变而改变的不可用共享的部分,实现要领就是区分应用中的两种状态,并将外部状态外部化

5.8.2.2 角色

  • 抽象享元角色(Flyweight):通常为一个抽象类或接口,在抽象享元类中声明了具体享元类公共方法,这些方法可以向外界提供享元对象的内部数据(内部态),同时也可通过这些方法来设置外部数据(外部态)
  • 具体享元(Concrete Flyweight)角色:实现了抽象享元类,称享元对象,在具体享元类中为内部状态提供了存储空间,通常可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象
  • 非享元(Unsharable Flyweight)角色:并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类,当需要一个非共享享元类的对象时可以直接通过实例化创建
  • 享元(Flyweight Factory)角色:负责创建和管理享元角色,当客户对象请求一个享元对象时,享元工厂检查系统中是否存在符合要求的享元对象,若存在就提供给客户,否则就创建一个新的享元对象

5.8.3 案例(俄罗斯方块)

  • 抽象享元角色
public abstract class AbstractBox {  
//    获取图形方法  
    public abstract String getShape();  
//    显示图形及颜色  
    public void display(String color){  
        System.out.println("方块形状:" + getShape() + ",颜色是:" + color);  
    }  
}
  • O图形类-具体享元角色
public class OBox extends AbstractBox{  
    @Override  
    public String getShape() {  
        return "O";  
    }  
}
  • I图形类-具体享元角色
public class IBox extends AbstractBox{  
    @Override  
    public String getShape() {  
        return "I";  
    }  
}
  • L图形类-具体享元角色
public class LBox extends AbstractBox{  
    @Override  
    public String getShape() {  
        return "L";  
    }  
}
  • 图形工厂-享元工厂
public class BoxFactory {  
    private HashMap<String,AbstractBox> map;  
//    构造方法中进行初始化操作  
    private BoxFactory() {  
        this.map = new HashMap<String,AbstractBox>();  
        this.map.put("I",new IBox());  
        this.map.put("L",new LBox());  
        this.map.put("O",new OBox());  
    }  
//    提供方法获得该类工厂对象  
    public static BoxFactory getInstance(){  
        return boxfactory;}  
    private static BoxFactory boxfactory = new BoxFactory();  
//    根据名称获取图形对象  
    public AbstractBox getShape(String name){  
        return map.get(name);  
    }  
}
  • 测试
public static void main(String[] args) {  
    //        获取I图形  
    AbstractBox box1 = BoxFactory.getInstance().getShape("I");  
    box1.display("红色");  
    //        获取L图形  
    AbstractBox box2 = BoxFactory.getInstance().getShape("L");  
    box2.display("白色");  
    //        获取O图形  
    AbstractBox box3 = BoxFactory.getInstance().getShape("O");  
    box3.display("绿色");  
    AbstractBox box4 = BoxFactory.getInstance().getShape("O");  
    box4.display("黑色");  
    System.out.println("两个O形图形是否一样:" + (box3 == box4));  
}
  • 结果![[Pasted image 20230105172017.png]]
  • 类图![[Pasted image 20230108155206.png]]

5.8.4 优缺点

5.8.4.1 优点

  • 极大减少内存中相似或相同对象数量,节约系统资源,提供系统性能
  • 享元模式中的外部状态相对独立,且不影响内部状态

5.8.4.2 缺点

为了使对象可以共享,需要将享元对象部分状态外部化,分离内部状态和外部状态,使程序逻辑复杂

5.8.5 使用场景

  • 一个系统有大量相同或相似对象,造成内存大量耗费
  • 对象大部分状态可以外部化,可以将这些外部状态传入对象中
  • 在使用享元模式时需维护一个存储享元对象的享元池,而这需耗费一定的系统资源,故应当在需要多次重复使用享元对象时才适合使用

5.8.6 JDK源码

  • Integer类使用了享元模式,如下
public static void main(String[] args) {  
    Integer i1 = 127;  
    Integer i2 = 127;  
    System.out.println((i1 == i2));  
    Integer i3 = 128;  
    Integer i4 = 128;  
    System.out.println((i3 == i4));  
}
  • 结果不同
    ![[Pasted image 20230105212536.png]]
  • 原因:
    • Integer类默认先创建并缓存-128-127之间数的Integer对象
    • 当调用valueOf时若参数在之间就计算下标从缓存中返回,否则就创建新的Integer对象

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

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

相关文章

图文并茂strapi 4.5.5自定义搭建指南以及数据库字段名接口返回mapping分析

strapi是什么&#xff1f; 基于Nodejs的开源免费CMS框架 为什么选择它&#xff1f; 基于nodejs,100&#xff05;JavaScript&#xff0c;上手迅速可轻松创建功能强大且可自定义的API可以使用任何喜欢的数据库 先决条件 首先你的电脑需要具备以下环境&#xff0c;再执行命令…

技术破局:程序员2023为何跳出舒适圈?

1前言今天的冬日暖阳高照&#xff0c;给我羽绒服下的肉身火一般的燥热&#xff0c;给了我一个错觉&#xff0c;以为到了阳春三月。刚刚送完老妈还有老婆孩子回老家&#xff0c;我坐到电脑机器前&#xff0c;准备捋一下思绪&#xff0c;回首2022的生活和工作。 2 2022 回顾今年用…

Linux下C/C++实现cpustat(测量CPU利用率)

在Linux中&#xff0c;cpustat定期转储正在运行的进程的当前CPU利用率统计信息。cpustat已被优化为具有最小的CPU开销&#xff0c;与top相比&#xff0c;通常使用约35%的CPU。cpustat还包括一些简单的统计分析选项&#xff0c;可以帮助描述CPU的加载方式。 cpustat介绍 cpust…

大数据概论

大数据概论大数据概论概念特点(4V)Volume(大量)Velocity(高速)Variety(多样)Value(低价值密度)应用场景发展前景部门间业务流程分析部门组织结构大数据概论 概念 大数据(BigData)&#xff0c;指无法在一定时间范围内\textcolor{Red}{无法在一定时间范围内}无法在一定时间范围…

iOS—Effective Objective—C2.0(2)

文章目录对象&#xff0c;消息&#xff0c;运行期理解“属性”概念合成与存取dynamic关键字属性特性原子性读/写权限内存管理语义方法名为什么几乎所有的属性都可以使用nonatomic&#xff1a;要点在对象的内部尽量直接访问实例变量惰性初始化&#xff1a;要点理解“对象同等性”…

2022年度总结——平凡之路

文章目录一、缘起二、回首2022三、展望2023四、结束语我是平凡的人&#xff0c;总要接受普通平凡的自己。一、缘起 我注册CSDN的时间是2021-07-25&#xff0c;这是一个值得纪念的时间。不过那时候的我并没有写博客&#xff0c;只是在CSDN游览一些文章&#xff0c;查看资料&…

一文读懂Java垃圾回收机制及算法原理万字详解

Java垃圾回收机制及算法 文章目录Java垃圾回收机制及算法垃圾回收概述垃圾回收-对象是否已死判断对象是否存活 - 引用计数算法判断对象是否存活-可达性分析算法可达性分析算法JVM之判断对象是否存活再谈引用垃圾收集算法分代收集理论标记-清除算法什么是标记-清除算法?标记-复…

读书:《卡片笔记写作法》

2023年罗胖跨年演讲时提到了一个故事&#xff0c;说Flomo的创始人有3个原则&#xff1a;一不在软件内弹广告&#xff0c;二不做永久会员&#xff0c;三不融资。我就马上试用了一下这款Flomo软件&#xff0c;然后就发现了《卡片笔记写作法》这本书。 这本书的卡片写作法来自于一…

【Qt】QtCreator新建Application项目的6类应用程序的示例

【Qt】QtCreator新建Application项目的6类应用程序的示例1、背景2、Application分类1、背景 操作系统&#xff1a;windows10专业版。 Qt版本&#xff1a;qt-opensource-windows-x86-msvc2013_64-5.7.1.exe 注意&#xff1a;安装了该exe可执行文件&#xff0c;就自动安装了qtcr…

(考研湖科大教书匠计算机网络)第一章概述-第一节:因特网概述

文章目录一&#xff1a;网络、互联网和因特网基本概念二&#xff1a;因特网发展的三个阶段三&#xff1a;ISP和基于ISP的三层结构的因特网&#xff08;1&#xff09;ISP&#xff08;2&#xff09;基于ISP的三层结构的因特网四&#xff1a;因特网的标准化工作五&#xff1a;因特…

KMP算法--子串查找问题

目录 一.前言 二.KMP算法简介 三.关键概念1&#xff1a;字符串的前后缀 四. 关键概念2&#xff1a;字符串相等前后缀与最长相等前后缀长度 五.关键概念3&#xff1a;Next数组 六.Next数组在算法中的应用&#xff1a; 七.模式串Next数组的构建 先膜拜一下三位神仙&#x…

面试前端数组去重,我会问这3个小问题

关于数组去重&#xff0c;已经是一个老生常谈的问题了&#xff0c;网络上已经有N篇关于数组去重的讲解了&#xff0c;所以&#xff0c;凡是能看见这篇博客的&#xff0c;我们都是有缘人&#xff0c;希望2023年你可以乘风破浪&#xff0c;职击沧海。而一般面试的时候&#xff0c…

MySQL调优-高性能业务表结构设计

目录 前言记录&#xff1a; 数据库表设计 范式设计 什么是范式&#xff1f; 数据库设计的第一范式 数据库设计的第二范式 数据库设计的第三范式 范式说明 反范式设计 什么叫反范式化设计&#xff1f; 反范式设计-商品信息 范式化和反范式总结 实际工作中的反范式实…

C++ stack和queue

1. stack的介绍和使用1.1 stack的介绍1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。2. stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&…

基于深度学习的自然语言处理

1、什么是自然语言处理&#xff1f; 自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门融语言学、计算机科学、…

【信号与系统】预习笔记(每日更新ing)

2023.1.8已打卡 信号与系统&#xff08;一&#xff09;信号与系统概述1.0 常见三角公式1.1 信号与系统1.2 信号的表述、分类1.3 信号的运算&#xff08;二&#xff09;连续系统的时域分析&#xff08;三&#xff09;离散系统的时域分析&#xff08;四&#xff09;傅里叶变换与频…

软件质量保证与软件测试复习文档

目录 引言&#xff1a; 内容&#xff1a; 一、Ron patton《软件测试》中谈到的软件缺陷的定义被业界广泛认可&#xff0c;主要包括哪五条&#xff1f; 二、软件测试人员的主要工作职责是什么&#xff0c;一般围绕哪几个重要文档开展工作&#xff1f; 三、什么是软件测试模…

差分算法介绍

一、基本概念 差分算法是前缀和算法的逆运算&#xff0c;可以快速的对数组的某一区间进行计算操作。 例如&#xff0c;有一数列 a[1],a[2],.…a[n]&#xff0c;且令 b[i] a[i]-a[i-1],b[1]a[1]&#xff0c;那么就有 a[i] b[1]b[2].…b[i] a[1]a[2]-a[1]a[3]-a[2].…a[i]-a[i…

电脑开机密码忘记了怎么办?

相信很多朋友为了保护自己的隐私&#xff0c;都会在自己的电脑设置开机密码&#xff0c;但有时候电脑太久没用&#xff0c;就有可能忘记开机密码了&#xff0c;这可怎么办&#xff1f;别着急&#xff0c;今天就跟大家分享两种苹果电脑忘记开机密码解决方式&#xff0c;适用于Ma…

使用Junit进行单元测试的简单例子

首先新建一个工程&#xff0c;选择合适的路径和JDK版本&#xff0c;其它默认就行。 把Main.java内容改为如下。 后面就是对add方法增加单元测试 public class Main {public static void main(String[] args) {System.out.println("Hello world!");}public static i…