享元设计模式

news2024/9/22 13:31:59

一、享元模式

1、定义

享元模式(Flyweight Pattern)又称作轻量级模式,是指提供减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享细粒度的对象,将多个对同一对象的访问集中起来,不必为每个访问者都创建一个单独的对象,以此来降低内存的消耗,属于结构型设计模式。

享元模式是对象池的一种实现,类似线程池,线程池可以避免不停地创建和销毁对个对象,消耗性能。

享元模式的本质是缓存共享对象,降低内存消耗。

2、结构

(1)模式的结构

主要角色如下:

  • 抽象享元角色(IFlyweight):享元对象抽象基类或者接口,同时定义出了对象的外部状态和内部状态的接口或实现。
  • 具体享元角色(ConcreteFlyweight):实现抽象角色定义的业务。该角色的内部状态处理应该与环境无关,不会出现一个操作改变内部状态、同时修改了外部状态的情况。
  • 享元工厂(FlyweightFactory):负责管理享元对象池和创建享元对象。

(2)享元模式的内部状态和外部状态

享元模式把一个对象的状态分为内部状态和外部状态

  • 内部状态:指对象共享出来的信息,存储在享元对象内部,并且不会随环境的改变而改变。
  • 外部状态:指对象得以依赖的一个标记,随环境的改变而改变,不可共享。

比如:连接池中的连接对象,保存在连接对象中的用户名、密码、URL等信息,在创建对象时就已经设置好了,不会随环境的改变而改变,这些为内部状态。而当每个连接对象要被回收利用时,我们需要将它标记为可用状态,这些为外部状态。

3、优缺点

优点:

  • 减少对象的创建,降低了内存中对象的数量,降低系统的内存,提高效率。
  • 减少内存之外的其他资源占用。

缺点:

  • 关注内、外部状态,关注线程安全问题。
  • 使系统、程序的逻辑复杂。

4、使用场景

  • 经常应用于系统底层的开发,来解决系统的性能问题。
  • 系统有大量相似对象,需要缓冲池的场景。

5、在框架源码中使用

  • Java中的 String类,Integer类中的IntegerCache等。
  • Apache源码中的 对象池(GenericObjectPoo l)。

二、模式的通用实现

代码如下:

public class FlyweightPattern {
    public static void main(String[] args) {
        IFlyweight flyweight1 = FlyweightFactory.getFlyweight("i-aaa");
        IFlyweight flyweight2 = FlyweightFactory.getFlyweight("i-bbb");
        IFlyweight flyweight3 = FlyweightFactory.getFlyweight("i-aaa");

        flyweight1.operation("e-123");
        flyweight1.operation("e-456");
        flyweight3.operation("e2-123");
    }
}

// 抽象享元角色

interface IFlyweight{
    void operation(String extrinsicState);
}

// 具体享元角色
class ConcreteFlyweight implements IFlyweight{
    private String intrinsicState;

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

    @Override
    public void operation(String extrinsicState) {
        System.out.println("对象 哈希地址:" + System.identityHashCode(this));
        System.out.println("内部状态:" + this.intrinsicState);
        System.out.println("外部状态:" + extrinsicState);
    }
}

// 享元工厂
class FlyweightFactory{
    private static Map<String, IFlyweight> pool = new HashMap<>();

    private FlyweightFactory() {
    }

    public static IFlyweight getFlyweight(String intrinsicState){
        // 由于内部状态具备不变性,所以作为缓存的键
        if(!pool.containsKey(intrinsicState)){
            IFlyweight flyweight = new ConcreteFlyweight(intrinsicState);
            pool.put(intrinsicState, flyweight);
            return flyweight;
        }
        return pool.get(intrinsicState);
    }
}

在这里插入图片描述

三、模式的应用实例

以数据库连接池为例,Connection连接对象再使用之前我们需要提前创建好并缓存起来,使用完毕之后,需要在放回去,来达到资源重复利用的目的。

public class ConnectionPool {
	private Vector<Connection> pool;

	private String url = "jdbc:mysql://localhost:3306/test_db";
	private String username = "root";
	private String pazzword = "123456";
	private String driverClassName = "com.mysql.cj.jdbc.Driver";
	private int poolSize = 100;

	public ConnectionPool() {
		pool = new Vector<>(poolSize);
		try {
			Class.forName(driverClassName);
			for (int i = 0; i < poolSize; i++) {
				Connection conn = DriverManager.getConnection(url, username, pazzword);
				pool.add(conn);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public synchronized Connection getConnection(){
		if(pool.size() > 0){
			Connection conn = pool.get(0);
			pool.remove(conn);
			return conn;
		}
		return null;
	}

	public synchronized void release(Connection conn){
		pool.add(conn);
	}

}

测试:

	public static void main(String[] args) throws SQLException {
		ConnectionPool connectionPool = new ConnectionPool();
		Connection conn = connectionPool.getConnection();

		conn.setAutoCommit(false);
		conn.createStatement();
		//conn.commit();

		connectionPool.release(conn);
	}

– 求知若饥,虚心若愚。

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

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

相关文章

C++智能指针shared_ptr用法

目录shared_ptr功能介绍shared_ptr提供的接口shared_ptr初始化shared_ptr管理指针的构造和析构shared_ptr获取原始指针shared_ptr的线程安全shared_ptr应用之enable_shared_from_this写在前面的总结&#xff1a;一个shared_ptr对象管理一个指针&#xff08;new T&#xff0c;在…

TCP/IP五层协议栈(3)

1.网络层 1.1.IP协议 IP协议格式:报头数据 4位版本 :IP协议的版本号.当前只有两个取值,4和6(0100 0110).( 这里讨论IPv4 )4位首部长度 :IP报头和TCP类似,都是可变的,带有选项.8位TOS :只有4位有效,那四位TOS分别表示( 最小延时,最大吞吐量,最高可靠性,最小成本 )(同一时刻只能…

使用 Qt for Android 获取并利用手机传感器数据(下篇)使用C++实现功能

在上一篇&#xff0c;我们搭建了开发环境。本篇&#xff0c;使用C代码真正实现功能。我们使用UDP协议从手机上指定发送的目的地、端口。效果如下图&#xff0c;完整工程参考https://gitcode.net/coloreaglestdio/qtcpp_demo/-/tree/master/android/sensors2pc&#xff1a; 移动…

全志T3 ARM+Ethercat+Codesys工业控制器设计方案

目前codesys EtherCAT驱动 做运动控制很有优势。现在总线式运动控制基本都是这种配置。 Codesys 号称PLC界的安卓&#xff0c;国内造PLC的 基本都用Codesys内核了。 如&#xff1a;汇川 &#xff0c;合信&#xff0c; 和利时 &#xff0c;英威腾&#xff0c; 台达。 包…

原子范数初探:以到达角估计为例

到达方向&#xff08;Direction-of-arrival, DOA&#xff09;估计是指从形成传感器阵列的多个接收天线的输出中检索若干电磁波/源的方向信息的过程。DOA估计是阵列信号处理中的一个主要问题&#xff0c;在雷达、声纳、无线通信中有着广泛的应用。 基本数学模型 考虑KKK个窄带…

Java项目:ssm流浪猫狗救助管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 流浪猫狗救助管理系统。该项目分为前后台&#xff1b; 前台主要功能包括&#xff1a;会员的注册登陆,流浪猫狗知识&#xff0c;领养中心&#…

[附源码]计算机毕业设计JAVA学生实习管理系统

[附源码]计算机毕业设计JAVA学生实习管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

80W美团架构师整理分享出了Spring5企业级开发实战文档

前言 都说程序员工资高、待遇好&#xff0c; 2022 金九银十到了&#xff0c;你的小目标是 30K、40K&#xff0c;还是 16薪的 20K&#xff1f;作为一名 Java 开发工程师&#xff0c;当能力可以满足公司业务需求时&#xff0c;拿到超预期的 Offer 并不算难。然而&#xff0c;提升…

U盘插入提示格式化才能使用,但里面有数据无法复制出来怎么解决?

U盘作为移动储存硬盘&#xff0c;避免不了出现各种问题&#xff0c;特别是莫名提示格式化&#xff0c;无法打开&#xff0c;要使用的话只能先将其格式化。 只要电脑还能正常识别出U盘&#xff0c;那都是有概率恢复出来数据的。先不要点“格式化”&#xff01; 如果一旦出现点…

4.JVM垃圾收集机制

1. 垃圾收集算法 1.1 分代收集理论 当前虚拟机的垃圾收集都采用分代收集算法&#xff0c;这种算法&#xff0c;没有什么新的思想&#xff0c;只是根据对象存活周期的不同将内存分成几块。一般将JAVA堆分为新生代、老年代&#xff0c;这样我们就可以根据各个年代的特点选择合适…

【注意力机制】Self-attention注意力机制理论知识

注意力机制目录输入输出类别&#xff08;N指向量个数&#xff09;&#xff1a;Self-attention引入self-attention架构self-attention怎么产生bbb例子&#xff1a;产生b1b^{1}b1例子&#xff1a;产生b2b^{2}b2self-attention 总结&#xff1a;Multi-head Self-attentionPosition…

使用 Learner Lab - 使用 API Gateway 与 Lambda 上传图片到 S3

使用 Learner Lab - 使用 API Gateway 与 Lambda 上传图片到 S3 AWS Academy Learner Lab 是提供一个帐号让学生可以自行使用 AWS 的服务&#xff0c;让学生可以在 100 USD的金额下&#xff0c;自行练习所要使用的 AWS 服务&#xff0c;如何进入 Learner Lab 请参考 使用 Lear…

【车载开发系列】UDS诊断---读取数据($0x22)

【车载开发系列】UDS诊断—读取数据&#xff08;$0x22&#xff09; UDS诊断---读取数据&#xff08;$0x22&#xff09;【车载开发系列】UDS诊断---读取数据&#xff08;$0x22&#xff09;一.概念定义二.报文格式1&#xff09;请求2&#xff09;肯定响应3&#xff09;否定响应三…

Vue中$nextTick实现源码解析

这篇文章主要为大家介绍了Vue中$nextTick实现源码解析&#xff0c;有需要的朋友可以借鉴参考下&#xff01; 先看一个简单的问题 {{ text }} 此时打印的结果是什么呢&#xff1f;是 old。如果想让它打印 new&#xff0c;使用 nextTick 稍加改造就可以 this.$nextTick(() >…

【计组笔记】06_指令系统

5.1 指令系统概述及指令格式 1. 指令的基本概念 2. 指令的分类 根据计算机层次结构分类 根据指令中地址码字段的个数分类 根据指令中操作数的物理位置分类 根据指令的功能分类 3. 指令格式 4. 指令的再认识 5. 指令格式举例 5.2 寻址方式及指令寻址 1. 寻址方式的概念 2.…

[论文阅读] 颜色迁移-Correlated Color Space

[论文阅读] 颜色迁移-Correlated Color Space 文章: Color transfer in correlated color space, [paper], [matlab code], [opencv code] 1-算法原理 本文算法比较简单, 其原理是把原始图像本身的空间分布进行归一化, 然后通过旋转平移缩放等变换, 变换到目标图像的空间分布…

WMS手动配货和自动配货的区别

手动配货 不知道配货流程的朋友可以看一下前面的文章链接: 深入浅出WMS之出库流程里面有对出库的解释说明&#xff0c;其中也有对配货的解释。前端页面也可以在前面的那篇文章中看到&#xff0c;这里我们来说一下后端部分。 查 手动配货是选中出库单的某条数据&#xff0c;然…

一文教你从Linux内核角度探秘JDK NIO文件读写本质(上)

1. 前言 在深入讲解Netty那些事儿之从内核角度看IO模型一文中曾对 Socket 文件在内核中的相关数据结构为大家做了详尽的阐述。 Socket内核结构.png 又在此基础之上介绍了针对 socket 文件的相关操作及其对应在内核中的处理流程&#xff1a; 系统IO调用结构.png 并与 epoll 的…

由阿里三位专家撰写:数据库高效优化:架构、规范SQL技巧文档

引言 学习是一种基础性的能力。然而&#xff0c;“吾生也有涯&#xff0c;而知也无涯。”&#xff0c;如果学习不注意方法&#xff0c;则会“以有涯随无涯&#xff0c;殆矣”。 学习就像吃饭睡觉一样&#xff0c;是人的一种本能&#xff0c;人人都有学习的能力。我们在刚出生…

[附源码]计算机毕业设计springboot作业管理系统

项目运行 环境配置&#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…