创建型(5种) 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式
结构型(7种) 适配器模式 装饰器模式 代理模式 外观模式 桥接模式 组合模式 享元模式
行为型(11种) 策略模式 模板方法模式 观察者模式 迭代器模式 责任链模式 命令模式 备忘录模式 状态模式 访问者模式 中介者模式
单例模式(Singleton Pattern)是一种创建型设计模式,其目标是在整个应用程序中确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。这种模式常用于那些需要严格控制全局唯一且共享访问点的场景,如数据库连接池、缓存管理器、日志记录器等。单例模式的核心特性包括:
- 唯一性:确保一个类仅有一个实例。
- 全局访问:提供一个全局访问点,使得任何地方都可以访问到这个唯一的实例。
模式结构
单例模式通常包含以下组成部分:
- 单例类:包含了创建并返回唯一实例的私有构造方法、保存唯一实例的私有静态变量,以及一个公有的静态方法(通常称为
getInstance()
)来获取这个唯一实例。
实现方式
单例模式有多种实现方式,常见的有两种:
饿汉式(Eager Initialization)
- 特点:类加载时立即初始化单例实例,线程安全,但可能导致资源浪费(如果单例在整个程序生命周期中并未被使用)。
1public class Singleton {
2 private static final Singleton INSTANCE = new Singleton();
3
4 private Singleton() {} // 私有构造方法防止外部直接实例化
5
6 public static Singleton getInstance() {
7 return INSTANCE;
8 }
9}
懒汉式(Lazy Initialization)
- 特点:首次访问时才初始化单例实例,延迟加载,节省资源。为了保证线程安全,通常需要同步访问或使用双重检查锁定(Double-Checked Locking)。
1public class Singleton {
2 private static volatile Singleton instance;
3
4 private Singleton() {} // 私有构造方法防止外部直接实例化
5
6 public static synchronized Singleton getInstance() {
7 if (instance == null) {
8 instance = new Singleton();
9 }
10 return instance;
11 }
12}
使用双重检查锁定优化的懒汉式单例:
1public class Singleton {
2 private static volatile Singleton instance;
3
4 private Singleton() {} // 私有构造方法防止外部直接实例化
5
6 public static Singleton getInstance() {
7 if (instance == null) {
8 synchronized (Singleton.class) {
9 if (instance == null) {
10 instance = new Singleton();
11 }
12 }
13 }
14 return instance;
15 }
16}
优缺点
优点
- 资源利用率:对于需要消耗大量资源的单例,懒汉式单例可以在真正需要时才初始化,避免资源浪费。
- 全局唯一:确保整个应用程序中单例类的实例只有一个,有利于资源的协调与共享。
- 控制全局状态:对于需要全局统一控制状态或行为的对象,单例模式可以提供一个集中的访问点。
缺点
- 灵活性受限:单例模式不利于代码的测试,特别是依赖于单例类的代码。在单元测试中,往往需要模拟不同的单例对象,而单例模式的单一实例特性对此造成了阻碍。
- 扩展困难:如果需要支持多个实例,或者需要实例化的时机有变化,单例模式难以应对。
- 并发问题:懒汉式单例如果不正确地实现线程安全性,可能导致多个实例被创建。在多线程环境下,需要仔细设计和实现以确保单例的正确性。
适用场景
- 需要频繁实例化然后销毁的对象:如线程池、数据库连接池等,通过单例模式可以减少频繁创建和销毁对象带来的性能开销。
- 需要严格控制全局状态的对象:如日志记录器、缓存、设备驱动等,通过单例模式可以确保整个系统中这些对象的状态一致。
- 需要保证数据共享与一致性:如配置文件读取、应用程序计数器等,通过单例模式可以避免数据的不一致性和重复加载。
总之,单例模式在需要控制对象实例数量为一、提供全局访问点且确保资源有效利用的场景中非常有用。但在设计时需要注意其对测试、扩展性和并发安全的影响,合理权衡使用。