架构系列——架构师必备基础:设计模式之单例模式(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

 

相关文章
|
23天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
27 2
|
4天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
12天前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入理解与应用
【10月更文挑战第22天】 在软件开发中,设计模式是解决特定问题的通用解决方案。本文将通过通俗易懂的语言和实例,深入探讨PHP中单例模式的概念、实现方法及其在实际开发中的应用,帮助读者更好地理解和运用这一重要的设计模式。
11 1
|
15天前
|
设计模式 API 持续交付
深入理解微服务架构:设计模式与实践
【10月更文挑战第19天】介绍了微服务架构的核心概念、设计模式及最佳实践。文章详细探讨了微服务的独立性、轻量级通信和业务能力,并介绍了聚合器、链式和发布/订阅等设计模式。同时,文章还分享了实施微服务的最佳实践,如定义清晰的服务边界、使用API网关和服务发现机制,以及面临的挑战和职业心得。
|
23天前
|
设计模式 测试技术 持续交付
架构视角下的NHibernate:设计模式与企业级应用考量
【10月更文挑战第13天】随着软件开发向更复杂、更大规模的应用转变,数据访问层的设计变得尤为重要。NHibernate作为一个成熟的对象关系映射(ORM)框架,为企业级.NET应用程序提供了强大的支持。本文旨在为有一定经验的开发者提供一个全面的指南,介绍如何在架构层面有效地使用NHibernate,并结合领域驱动设计(DDD)原则来构建既强大又易于维护的数据层。
35 2
|
24天前
|
缓存 NoSQL Java
秒杀圣经:10Wqps高并发秒杀,16大架构杀招,帮你秒变架构师 (1)
高并发下,如何设计秒杀系统?这是一个高频面试题。40岁老架构师尼恩的读者交流群中,近期有小伙伴在面试Shopee时遇到了这个问题,未能很好地回答,导致面试失败。为此,尼恩进行了系统化、体系化的梳理,帮助大家提升“技术肌肉”,让面试官刮目相看。秒杀系统设计涉及16个架构要点,涵盖业务架构、流量架构、异步架构、分层架构、缓存架构、库存扣减、MQ异步处理、限流、熔断、降级、存储架构等多个方面。掌握这些要点,可以有效应对高并发场景下的秒杀系统设计挑战。
秒杀圣经:10Wqps高并发秒杀,16大架构杀招,帮你秒变架构师 (1)
|
18天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
21 0
|
20天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
本教程详细讲解了Kotlin中的单例模式实现,包括饿汉式、懒汉式、双重检查锁、静态内部类及枚举类等方法,适合需要深入了解Kotlin单例模式的开发者。快速学习者可参考“简洁”系列教程。
27 0
|
21天前
|
设计模式 存储 数据库连接
Python编程中的设计模式之美:单例模式的妙用与实现###
本文将深入浅出地探讨Python编程中的一种重要设计模式——单例模式。通过生动的比喻、清晰的逻辑和实用的代码示例,让读者轻松理解单例模式的核心概念、应用场景及如何在Python中高效实现。无论是初学者还是有经验的开发者,都能从中获得启发,提升对设计模式的理解和应用能力。 ###
|
23天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
下一篇
无影云桌面