详解设计模式:享元模式

news2024/11/27 4:02:31

享元模式(Flyweight Pattern),是对象池的一种体现,也是 GoF 的 23 种设计模式中的一种结构型设计模式。

享元模式 主要用于减少创建对象的数量,以减少内存占用和提高性能。它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元模式 尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

~

本篇内容包括:关于享元模式、享元模式 Demo


文章目录

    • 一、关于享元模式
        • 1、关于享元模式
        • 2、关于享元模式的构成
        • 3、关于享元模式的XML
        • 4、关于享元模式的应用场景
        • 5、关于享元模式在 Java 中的应用
        • 6、关于享元模式的优缺点
    • 二、享元模式 Demo
        • 1、Demo 设计
        • 2、Demo 实现


一、关于享元模式

1、关于享元模式

享元模式(Flyweight Pattern),是对象池的一种体现,也是 GoF 的 23 种设计模式中的一种结构型设计模式。

享元模式 主要用于减少创建对象的数量,以减少内存占用和提高性能。它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元模式 尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

2、关于享元模式的构成

享元模式主要包含四种角色:

  1. 抽象享元(Flyweight)角色:是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
  2. 具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
  3. 非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
  4. 享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

3、关于享元模式的XML

享元模式

4、关于享元模式的应用场景

当系统中多处需要同一组信息时,可以吧这些信息封装到一个对象中,然后对该对象进行缓存,这样,一个对象就可以提供给多处需要使用的地方,避免大量同一对象多次创建,消耗大量内存空间。
享元模式其实就是工厂模式的一个改进机制,享元模式同样要求创建一个或一组对象,并且就是通过工厂方法生成对象的,只不过享元模式中为工厂方法增加了缓存这一功能。主要总结为以下应用场景:

  1. 常常应用于系统底层的开发,以便解决系统的性能问题。
  2. 系统有大量相似的对象、需要缓存池的场景。

在生活中的享元模式也很常见,比如中介机构的房源共享,再比如全国社保联网。

5、关于享元模式在 Java 中的应用

在 Java 中最直观的享元模式就是在 Boolean,Byte,Integer,Long,Character 这些包装类中,他们都提供了valueOf()方法。

比如:Long 的 valueOf() 方法会缓存数值 -127~128 之间的 Long 对象,在这个范围之间就会直接在这个里面去取,大于这个范围才会去 new Long 对象

public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }

Byte,Short,Long 的范围是 -127~128 之间。

Character 是 0~127 之间。

Integer 是 -127~128 之间,最小值不能改变,但是最大值可以通过虚拟机参数进行改变。-Djava.long.Intger.IntegerCache.high 来改变

Boolean 缓存了 TRUE 和 FALSE

6、关于享元模式的优缺点

# 享元模式的优点:

  1. 减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率;
  2. 减少内存之外的其它资源占用。

# 享元模式的缺点:

  1. 关注内、外部状态、关注线程安全问题;
  2. 使系统、程序复杂化。

二、享元模式 Demo

1、Demo 设计

俄罗斯方块有不同的形状,我们可以对这些形状向上抽取出 AbstractBox,用来定义共性的属性和行为。

接下来就是定义不同的形状了,IBox类、LBox类、TBox类等。

提供了一个工厂类(BoxFactory),用来管理享元对象(也就是 AbstractBox 子类对象),该工厂类对象只需要一个,所以可以使用单例模式。并给工厂类提供一个获取形状的方法。

2、Demo 实现

# AbstractBox 抽象享元角色

public abstract class AbstractBox {
    public abstract String getShape();

    public void display(String color) {
        System.out.println("方块形状:" + this.getShape() + " 颜色:" + color);
    }
}

# IBox/LBox/TBox 具体享元角色

public class IBox extends AbstractBox {

    @Override
    public String getShape() {
        return "I";
    }
}

public class LBox extends AbstractBox {

    @Override
    public String getShape() {
        return "L";
    }
}

public class TBox extends AbstractBox {

    @Override
    public String getShape() {
        return "T";
    }
}

# BoxFactory 享元工厂

public class BoxFactory {

    private static HashMap<String, AbstractBox> map;

    private BoxFactory() {
        map = new HashMap<String, AbstractBox>();
        AbstractBox iBox = new IBox();
        AbstractBox lBox = new LBox();
        AbstractBox oBox = new OBox();
        map.put("I", iBox);
        map.put("L", lBox);
        map.put("O", oBox);
    }

    public static final BoxFactory getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        private static final BoxFactory INSTANCE = new BoxFactory();
    }

    public AbstractBox getBox(String key) {
        return map.get(key);
    }
}

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

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

相关文章

[附源码]Python计算机毕业设计SSM跨移动平台的新闻阅读应用(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

二、Eureka服务注册与发现

Eureka服务注册与发现 Eureka基础知识 什么是服务治理 SpringCloud封装了Netflix公司开发的Eureka模块来实现服务治理。 在传统的RPC远程调用框架中&#xff0c;管理每个服务与服务之间依赖关系比较复杂、所以需要进行服务治理&#xff0c;管理服务与服务之间依赖关联&…

网上商店商城购物系统(asp.net,sqlserver,三层架构)

网上商店商城购物系统(asp.net,sqlserver,三层)(毕业论文10000字以上,程序代码,SqlServer数据库) 【运行环境】 VisualStudio SqlServer 代码下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1gzX_-Dzrt5jDHvQOCTN7qQ 提取码&#xff1a;8888 【项目包含内容…

Docker with IPV6

1、绪论 在 Docker 容器或群服务中使用 IPv6 之前&#xff0c;您需要在 Docker 守护进程中启用 IPv6 支持。之后&#xff0c;您可以选择对任何容器、服务或网络使用 IPv4 或 IPv6&#xff08;或两者&#xff09; 2、配置默认 Docker IPv6 注意&#xff1a;IPv6 网络仅在 Lin…

vue - vue使用webpack-bundle-analyzer进行代码打包的可视化数据分析

vue使用webpack-bundle-analyzer插件可以明确的看出每个文件模块的大小&#xff1b;常用来分析打包文件&#xff0c;优化代码等操作&#xff1b; 安装使用之后的效果如下&#xff1a;启动或打包项目&#xff0c;自动会在浏览器打开这个页面; 可以看出&#xff1a;右上角最蓝色的…

蓝牙学习五(广播包分析wireshark)

1.简介 软件工具&#xff1a;wireshark 硬件抓包工具&#xff1a;nrf52840 dongle 2.数据包分析 使用wireshark抓到的数据包分为两个部分&#xff0c;一部分是软件自己添加的内容&#xff0c;另一部分才是广播出来的数据。 2.1软件添加部分 软件添加的大部分内容可以不关注。这…

结构力学常用公式表,早晚用得到!

来源&#xff1a;360个人图书馆 常用截面几何与力学特征表​​​​​​​ 注&#xff1a; I 称为截面对主轴&#xff08;形心轴&#xff09;的截面惯性矩 (mm4)。基本计算公式如下&#xff1a; W称为截面抵抗矩 (mm)&#xff0c;它表示截面抵抗弯曲变形能力的大小&#xff0c…

SQL29 计算用户的平均次日留存率

原题链接 【描述】 题目&#xff1a;现在运营想要查看用户在某天刷题后第二天还会再来刷题的平均概率。请你取出相应数据。 【示例】&#xff1a;question_practice_detail 【题目分析】摘自题解区"Reg333"的题解 所谓次日留存&#xff0c;指的是同一用户&#x…

4-3:点赞功能

点赞 点赞 支持对帖子、评论点赞。第1次点赞&#xff0c;第2次取消点赞。 首页点赞数量统计帖子的点赞数量。 详情页点赞数量统计点赞数量。显示点赞状态。 Redis缓存用于点赞功能&#xff0c;可以提高性能。&#xff08;面向Key编程&#xff09; 1.建立RedisKeyUtil.java p…

力扣刷题记录162.1-----127. 单词接龙

目录一、题目二、代码三、运行结果一、题目 二、代码 class Solution { public://广度优先搜索int ladderLength(string beginWord, string endWord, vector<string>& wordList) {int i,j;//将vector转换成unordered_st 提高查询速度 目前理解不深unordered_set&l…

如何判断对象是否是垃圾

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 我们都Java会自动进行内存管理&#xff0c;JVM会进行垃圾回收&#xff0c;哪它是怎么判定哪些是“垃圾”并决定“垃圾”的生死呢&#xf…

【allegro 17.4软件操作保姆级教程七】布线操作基础之二--铜皮操作

目录 1.1全局动态铜皮参数设置 1.2手动绘制铜皮 1.3手动挖铜 1.4 手动修改铜皮边界 1.5删除孤岛铜皮 1.6动/静态铜皮转换 1.7合并铜皮 1.8平面铺铜和铜皮分割 1.9铜皮颜色设置 今天分享布线操作技巧中的铜皮操作。 1.1全局动态铜皮参数设置 单板上的电源部分、铺地都…

【网安神器篇】——wmic_info信息收集工具

作者名&#xff1a;Demo不是emo 主页面链接&#xff1a;主页传送门 创作初心&#xff1a;舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座…

2万字一网通办远程视频踏勘建设方案67页

目 录 1. 建设背景 2. 建设周期 3. 需求分析 3.1. 需求定义 3.1.1. 需求活动目的 3.1.2. 需求分析流程 3.2. 技术需求 3.3. 用户分析 3.3.1. 办事企业 3.3.2. 踏勘人员 3.3.3. 审批人员 3.3.4. 系统管理人员 3.4. 性能需求 3.4.1. 系统架构 3.4.2. 响应时间 3.…

π110E30 单通道数字隔离器兼容代替Si8610BC-B-IS

π110E30 单通道数字隔离器兼容代替Si8610BC-B-IS 。具有出色的性能特征和可靠性&#xff0c;整体性能优于光耦和基于其他原理的数字隔离器产品。 传输通道间彼此独立&#xff0c;可实现多种传输方向的配置&#xff0c;可实现 1.5kV rms 到 5.0kV rms 隔离耐压等级和 DC 到 600…

MyBatis-Plus中查询操作知识点总结

系列文章目录 Mybatis-Plus知识点[MyBatisMyBatis-Plus的基础运用]_心态还需努力呀的博客-CSDN博客 Mybatis-PlusSpringBoot结合运用_心态还需努力呀的博客-CSDN博客 MyBaits-Plus中TableField和TableId用法_心态还需努力呀的博客-CSDN博客 MyBatis-Plus删除操作知识点总结…

【Android App】物联网中指南针、计步器、感光器、陀螺仪的讲解及实战演示(附源码 超详细必看)

需要源码请点赞关注收藏后评论区留言~~~ 一、指南针-磁场传感器 顾名思义&#xff0c;指南针只要找到朝南的方向就好了。 可是在App中并非使用一个方向传感器这么简单&#xff0c;事实上单独的方向传感器已经弃用&#xff0c;取而代之的是利用加速度传感器和磁场传感器。 获得…

区块链工作原理(区块链治理系统、比特币、以太坊、智能合约)

文章目录Blockchain Governance SystemOn-Chain GovernanceOff-Chain GovernanceBitCoin BlockchainEthereum BlockchainProperties of Blockchain SystemSmart ContractsScalability Issues in Blockchain SystemsBlockchain Governance System 每个国家或者城市都有自己的一…

我的第一个网页之----使用HTML编辑器编写HTML文档

HTML篇_三、使用HTML编辑器编写HTML文档 为了满足使用HTML语言进行学习、开发需求我们还需要选择使用一款开发工具来使用。我们可以选择更专业的开发工具来使用&#xff0c;在这里简单介绍几款本人使用过的开发工具&#xff0c;选择你的趁手武器。 一、简述几款HTML编辑器 1…

Proxmox VE 彻底删除本地存储

作者&#xff1a;田逸&#xff08;formyz&#xff09; 问题描述 从Proxmox VE web管理后台添加本地存储&#xff0c;如LVM、LVM-Thin&#xff08;精简逻辑卷&#xff09;等&#xff0c;有时候可能需要删除这些存储&#xff0c;但其Web管理后台却没有提供菜单或者按钮。要删除这…