设计模式——多例模式(23种之外)

多例模式(Multiton Pattern)是一种特殊的设计模式,它属于创建型模式。与单例模式(Singleton Pattern)相比,多例模式允许一个类有多个实例,但是实例的数量是有限制的,并且这些实例在全局范围内是共享的。这种模式适用于当系统中有且仅有几个对象实例被频繁使用,且这些对象的创建和销毁开销较大时。

在我的SpringBoot项目中遇到的一个问题,最后使用多例模式解决了。问题是我需要通过传入参数实例化一个对象,希望如果出入的参数相同那么得到的实例应该是一样的,如果参数不同则实例化的参数是不同的。这个问题我一开始想到了单例模式和工厂模式结合来解决,在工厂中判断参数是否已经存在从而创建单例实例,后面越想越觉得自己搞复杂了,虽然可以解决这个问题,最后果然发现还有一种多例模式可以完美解决这个问题。那么,下面就开始演示如何使用多例模式:

需要实例化的User类

public class User {String id;public User(String id) {this.id = id;}public String getId() {return id;}public void setId(String id) {this.id = id;}@Overridepublic String toString() {return "User{" +"id='" + id + '\'' +'}';}
}

直接获取对象的缺点

我们正常的实例化其实是不满足条件的,例如如下代码:

public class MainTest {public static void main(String[] args) { User user1 = new User("123");User user2 = new User("123");System.out.println(user1.hashCode());System.out.println(user2.hashCode());System.out.println(user1 == user2);}
}

输出结果

128893786
1732398722
false

显然,这样new出来的两个对象不是同一个,但是在这种情况下,我们希望通过参数构造的对象只要参数相同就能拿到同一个对象,类似单例模式,而不同参数则创建新的对象。这种情况就非常适合多例模式,下面介绍多例模式解决这个问题。

多例模式

多例模式的特点

  • 实例数量有限:与单例模式不同,多例模式允许创建多个实例,但实例的数量是有限的。
  • 全局访问:所有实例都是全局可访问的,通常通过一个全局的访问点来获取实例。
  • 实例唯一性:在允许的范围内,每个实例都是唯一的。

下面是线程安全的实现,这里我们使用一个工厂类来管理我们的User,只要是相同的id就一定能够获得相同的User,不同的id拿到的User不同。代码如下:

public class UserMultitonFactory {private static final ConcurrentHashMap<String, User> userMap = new ConcurrentHashMap<>();private UserMultitonFactory(){} // 私有构造方法防止new实例化public static User getInstance(String id) {// 使用computeIfAbsent方法确保线程安全的实例创建return userMap.computeIfAbsent(id,k -> new User(k)); // 这个k就是id}public static void destroyInstance(String id){userMap.remove(id);}
}

测试

public class MainTest {public static void main(String[] args) {User user1 = UserMultitonFactory.getInstance("123");User user2 = UserMultitonFactory.getInstance("123");User user3 = UserMultitonFactory.getInstance("001");System.out.println(user1.hashCode());System.out.println(user2.hashCode());System.out.println(user3.hashCode());}
}

结果

1108411398
1108411398
1394438858

这里我们是使用一个工厂类来管理User的创建,当然也可以让User自己成为一个多例模式类,代码如下:


public class UserMultiton {String id;private static final ConcurrentHashMap<String, UserMultiton> userMap = new ConcurrentHashMap<>();private UserMultiton(String id) { // 禁止外部创建该类this.id = id;}public static UserMultiton getInstance(String id){// 使用computeIfAbsent方法确保线程安全的实例创建return userMap.computeIfAbsent(id,k -> new UserMultiton(k)); // 这个k就是id}public static void destroyInstance(String id){userMap.remove(id);}public String getId() {return id;}public void setId(String id) {this.id = id;}@Overridepublic String toString() {return "User{" +"id='" + id + '\'' +'}';}
}

应用场景

多例模式是一种创建型设计模式,其应用场景主要在于管理可重复使用的资源,如线程池、数据库连接池等。这些场景中,多例模式能够复用已有实例,避免重复创建对象,从而提高系统性能并避免浪费系统资源。

缺点

多例模式的缺点包括:

  • 难以扩展:多例模式的实例数量是固定的,难以动态地增加或减少实例数量。
  • 难以测试:由于多例模式的实例数量是固定的,难以对每个实例进行单独的测试。
  • 破坏封装性:多例模式需要全局访问实例,这破坏了封装性,使得代码难以维护和扩展。
  • 代码复杂度高:多例模式的实现需要考虑线程安全、序列化等问题,因此代码复杂度较高。

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

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

相关文章

【Linux】Ubuntu配置JDK环境、MySQL环境

一、 Ubuntu配置JDK环境 在Ubuntu系统中安装JDK 8可以通过以下步骤进行&#xff1a; 打开终端。更新包列表&#xff1a; sudo apt update安装OpenJDK 8&#xff1a; sudo apt install openjdk-8-jdk验证安装是否成功&#xff1a; java -version注&#xff1a;如果系统中安…

4.10、matlab生成脉冲序列:pulstran()函数

1、matlab生成脉冲序列简介 MATLAB生成脉冲序列通常涉及到使用MATLAB中的函数或编程来创建具有特定时间间隔和幅度的脉冲信号。脉冲序列通常用于数字信号处理、通信系统测试等应用中。 生成脉冲序列可以采用以下方法之一: 使用MATLAB中的函数,例如square()函数生成方波信号…

FreeRTOS 入门 知识

什么是FreeRTOS FreeRTOS 是一个轻量级的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;由 Richard Barry 在 2003 年开发&#xff0c;并且由亚马逊的 FreeRTOS 项目&#xff08;一个由 Amazon Web Services (AWS) 支持的开源项目&#xff09;进一步推动和发展。FreeR…

麒麟系统开发笔记(十四):在国产麒麟系统上编译libmodbus库、搭建基础开发环境和移植测试Demo

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140387947 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

Java--接口的定义与实现

1.Java的接口是一种约束 2.定义一些方法&#xff0c;让不同的人实现 3.方法都是 public abstract 4.常量都是public static final 5.接口不能被实例化&#xff1a; 接口中没有构造方法 6.接口可以多继承&#xff1a; 使用implements即可实现 7.必须要重写接口中的方法…

什么是稀疏化

稀疏化一词来源于条件计算理念。在稠密模型中&#xff0c;所有参数都发挥作用&#xff0c;而稀疏化可以只运行整个系统的某些部分。 前文提到 Shazeer 对机器翻译中的 MoE 进行了探索。条件计算&#xff08;网络中只有某些部分处于活动状态&#xff09;使得在不增加计算量的情况…

差分进化算法与遗传算法之间的区别

差分进化算法&#xff08;Differential Evolution, DE&#xff09;和遗传算法&#xff08;Genetic Algorithm, GA&#xff09;都是基于进化思想的优化算法&#xff0c;用于全局优化问题。尽管它们有许多相似之处&#xff0c;但在具体实现和应用上有明显的区别。 共同点 种群进…

Android系统上常见的性能优化工具

Android系统上常见的性能优化工具 以下是一些常见的性能优化工具&#xff0c;可用于辅助分析 Systrace 报告&#xff1a; Android Studio Profiler&#xff1a;它集成在 Android Studio 中&#xff0c;提供了 CPU、内存、网络等多方面的性能分析功能&#xff0c;能与 Systrace…

在家上网IP地址是固定的吗?

在数字化时代&#xff0c;互联网已成为我们日常生活中不可或缺的一部分。无论是工作、学习还是娱乐&#xff0c;我们都离不开网络的支持。然而&#xff0c;当我们在家中接入互联网时&#xff0c;可能会产生这样一个疑问&#xff1a;在家上网IP地址是固定的吗&#xff1f;下面一…

SpinalHDL之实用工具(下篇)

本文作为SpinalHDL学习笔记第十四篇&#xff0c;记录使用SpinalHDL的一些实用性语法工具。 SpinalHDL学习笔记总纲链接如下&#xff1a; SpinalHDL 学习笔记_spinalhdl blackbox-CSDN博客 目录&#xff1a; 6.存根&#xff08;Stub&#xff09; 7.Assertions 8.Report 9.S…

秋招Java后端开发冲刺——MyBatisPlus总结

一、 基本知识 1. 介绍 yBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上增加了大量功能和简化操作&#xff0c;以提高开发效率。 2. 特点 无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对现有项目产生影响。依赖少&#xff1a;仅仅依赖 …

探索 Java 8 新特性:函数式接口

Java 8 的发布为 Java 语言带来了许多重要的改进和新特性。其中&#xff0c;函数式接口&#xff08;Functional Interface&#xff09;是一个关键的概念&#xff0c;它与 Lambda 表达式紧密相关&#xff0c;为简化代码和提高可读性提供了强有力的支持。本文将深入探讨函数式接口…

数仓工具—Hive语法之正则表达式函数

正则表达式函数 之前我们介绍过like rlike regexp 这些关键字,都是和匹配有关的,今天我们介绍一下hive 的REGEXP_REPLACE 和REGEXP_EXTRACT 函数,背景是使用Hive正则表达式函数提取数字 在我的其他文章中,我们已经看到了如何使用Hive正则表达式从字符串中提取日期值。正则…

CV05_深度学习模块之间的缝合教学(1)

1.1 在哪里缝 测试文件&#xff1f;&#xff08;&#xff09; 训练文件&#xff1f;&#xff08;&#xff09; 模型文件&#xff1f;&#xff08;√&#xff09; 1.2 骨干网络与模块缝合 以Vision Transformer为例&#xff0c;模型文件里有很多类&#xff0c;我们只在最后…

Ubuntu 软件源404not found原因及解决办法

报错原因 404的意思是没有找到这个源。原因如下&#xff1a; 软件源链接有问题。可能是不符合你的架构的链接&#xff08;如ubuntu x86架构使用了ubuntu arm架构的软件源链接&#xff09;&#xff0c;或者不符合当前版本的链接&#xff08;ubuntu 22.04使用了ubuntu 24的链接…

huggingface 数据集和模型加速下载, hfdata 输出为json

如果有碰到huggingface的数据集下载慢&#xff0c;可以使用国内镜像代理下载&#xff0c;首先打开命令行&#xff0c;输入下面的环境变量&#xff1a; export HF_ENDPOINThttps://hf-mirror.com然后执行你自己的代码&#xff0c;比如&#xff1a; from datasets import load_…

嘉立创EDA隐藏地线或者

https://prodocs.lceda.cn/cn/pcb/side-panel-left-net/#%E9%A3%9E%E7%BA%BF

50+dfm模型素人网红路人实时直播替换DFLive模型dfm格式

作为一名直播达人&#xff0c;我投入了大量时间和精力在网上收集和购买各种直播所需的模型资源。这些资源不仅包括男模、女模&#xff0c;还有明星脸、大众脸、网红脸以及各类稀有的素人模型。为了回馈广大直播爱好者&#xff0c;我将这些宝贵资源整理成一个合集&#xff0c;供…

elasticsearch性能调优方法原理与实战

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

【Android面试八股文】Android 中如何捕获未捕获的异常?

在 Android 应用开发中,捕获未捕获的异常(Uncaught Exception)通常需要通过设置全局异常处理器来实现。这样可以在应用程序中的任何位置捕获到未被处理的异常,并进行相应的处理或记录。 一、设置全局异常处理器 Android 应用可以通过 Thread.setDefaultUncaughtException…