架构系列——架构师必备基础:设计模式之单例模式(Singleton Pattern)

简介: 架构系列——架构师必备基础:设计模式之单例模式(Singleton Pattern)

前言

单例模式,就是在整个应用程序中都只有一个实例,并且提供一个类方法来供全局调用,在编译期间会一直存储在内存中,直到程序退出,系统自动释放此内存。

下面这个图是不是很熟悉,这个是任务管理器。

你可以尝试一下,在一个电脑上,打开一个任务管理器之后,再打开一次任务管理器,这时候桌面上不会产生新的任务管理器!这是单例模式,也就是说,整个windows系统只存在一个任务管理器的实例!

电脑上的回收站也是同样的道理。

一、单例模式优点

一个类只能产生一个实例,这样做的好处有:

1.减少内存开支

当你想关闭QQ进程的时候,可以使用任务管理器;当你想关闭浏览器的时候,也可以使用任务管理器。当然,两次打开的任务管理器其实是同一个任务管理器。这样的话,电脑的CPU就会减少一部分开销!

2.避免状态切换时的不正确

假如打开了两个任务管理器A和B,关闭A里面的QQ的话,那么B中的QQ有那么一刻没有及时更新,微软肯定不能接受这样的效果!

二、单例模式的实现与选择

1.单例模式的实现

网上有很多,这里推荐实现方式:

设计模式之单例模式--runoob

2.怎么选择单例模式

(1)如果单例对象占用资源少,不需要延迟加载,那么枚举式优于饿汉式

(2)如果单例对象占用资源大,需要延时加载,那么静态内部类式优于懒汉式

三、单例模式破解

菜鸟教程给的只是案例,如果没有对代码优化的话,可以通过以下两种方式破解单例!

1.1通过反射破解

/**
 * 测试反射破解单例模式
 */
public class Reflect {
  public static void main(String[] args) throws Exception {
    // 通过反射直接调用私有构造器破解单例模式
    Class<RuleManager> clz = (Class<Singleton>) Class.forName("com.Singleton");
    Constructor<Singleton> constructor = clz.getDeclaredConstructor(null);
    constructor.setAccessible(true);
    Singleton s3 = constructor.newInstance();
    Singleton s4 = constructor.newInstance();
    System.out.println(s3);
    System.out.println(s4);
  }
}


打印出来的s3和s4结果不一样,说明已经破解了!

1.2解决方法

获取对象的时候手动抛出异常

if (instance!=null) {
   throw new RuntimeException();
}

2.1 通过序列化与反序列化破解

//获取单例
Singleton s1 = Singleton.getInstance();
//将序列化到本地文件
FileOutputStream fos = new FileOutputStream("d:/test.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(s1);
oos.close();
fos.close();
//反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/test.txt"));
Singleton s2 =  (Singleton) ois.readObject();
Singleton s3 =  (Singleton) ois.readObject();
System.out.println(s2);
System.out.println(s3);

2.2 解决方法

在生成单例的类里加入readResolve方法

private Object readResolve() throws ObjectStreamException {
   return instance;
}


四、单例模式的应用

windows中任务管理器,回收站

常见的工具类

数据库连接类

项目中用于读取配置文件的类

Spring中,每个Bean默认都是单例的,这样便于Spring容器进行管理

网站计数器

Servlet中Application

 

相关文章
|
2月前
|
存储 消息中间件 Kafka
Confluent 首席架构师万字剖析 Apache Fluss(二):核心架构
原文:https://jack-vanlightly.com/blog/2025/9/2/understanding-apache-fluss 作者:Jack Vanlightly 翻译:Wayne Wang@腾讯 译注:Jack Vanlightly 是一位专注于数据系统底层架构的知名技术博主,他的文章以篇幅长、细节丰富而闻名。目前 Jack 就职于 Confluent,担任首席技术架构师,因此这篇 Fluss 深度分析文章,具备一定的客观参考意义。译文拆成了三篇文章,本文是第二篇。
284 19
|
5月前
|
设计模式 SQL 人工智能
Python设计模式:从代码复用到系统架构的实践指南
本文以Python为实现语言,深入解析23种经典设计模式的核心思想与实战技巧。通过真实项目案例,展示设计模式在软件开发中的结构化思维价值,涵盖创建型、结构型、行为型三大类别,并结合Python动态语言特性,探讨模式的最佳应用场景与实现方式,帮助开发者写出更清晰、易维护的高质量代码。
208 1
|
5月前
|
设计模式 人工智能 算法
Python设计模式:从代码复用到系统架构的实践指南
本文探讨了电商系统中因支付方式扩展导致代码臃肿的问题,引出设计模式作为解决方案。通过工厂模式、策略模式、单例模式等经典设计,实现代码解耦与系统扩展性提升。结合Python语言特性,展示了模块化、装饰器、适配器等模式的实战应用,并延伸至AI时代的设计创新,帮助开发者构建高内聚、低耦合、易维护的软件系统。
323 0
|
7月前
|
设计模式 缓存 安全
【设计模式】【创建型模式】单例模式(Singleton)
一、入门 什么是单例模式? 单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。它常用于需要全局唯一对象的场景,如配置管理、连接池等。 为什么要单例模式? 节省资源 场景:某些对象创
254 15
|
9月前
|
设计模式 机器学习/深度学习 前端开发
Python 高级编程与实战:深入理解设计模式与软件架构
本文深入探讨了Python中的设计模式与软件架构,涵盖单例、工厂、观察者模式及MVC、微服务架构,并通过实战项目如插件系统和Web应用帮助读者掌握这些技术。文章提供了代码示例,便于理解和实践。最后推荐了进一步学习的资源,助力提升Python编程技能。
|
9月前
|
设计模式 Java 数据安全/隐私保护
Java 设计模式:装饰者模式(Decorator Pattern)
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。
|
9月前
|
设计模式 安全 Java
设计模式:单例模式
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点。它通过私有化构造函数、自行创建实例和静态方法(如`getInstance()`)实现。适用于数据库连接池、日志管理器等需要全局唯一对象的场景。常见的实现方式包括饿汉式、懒汉式、双重检查锁、静态内部类和枚举。线程安全问题可通过`synchronized`或双重检查锁解决,同时需防止反射和序列化破坏单例。优点是避免资源浪费,缺点是可能增加代码耦合度和测试难度。实际开发中应优先选择枚举或静态内部类,避免滥用单例,并结合依赖注入框架优化使用。
|
8月前
|
设计模式 存储 安全
设计模式-单例模式练习
单例模式是Java设计模式中的重要概念,确保一个类只有一个实例并提供全局访问点。本文详解单例模式的核心思想、实现方式及线程安全问题,包括基础实现(双重检查锁)、懒汉式与饿汉式对比,以及枚举实现的优势。通过代码示例和类图,深入探讨不同场景下的单例应用,如线程安全、防止反射攻击和序列化破坏等,展示枚举实现的简洁与可靠性。
142 0
|
10月前
|
设计模式 存储 安全
设计模式2:单例模式
单例模式是一种创建型模式,确保一个类只有一个实例,并提供全局访问点。分为懒汉式和饿汉式: - **懒汉式**:延迟加载,首次调用时创建实例,线程安全通过双重检查锁(double check locking)实现,使用`volatile`防止指令重排序。 - **饿汉式**:类加载时即创建实例,线程安全但可能浪费内存。 示例代码展示了如何使用Java实现这两种模式。
233 4

热门文章

最新文章