Singleton 是Gang of Four 设计模式的一部分,属于创建型设计模式。在本文中,我们将深入研究单例模式的用法。就建模而言,它是最简单的设计模式之一,但另一方面,就使用的复杂性而言,这是最具争议的模式之一。
单例模式是一种设计模式,它限制一个类实例化它的多个对象。它只不过是定义类的一种方式。类以这样一种方式定义,即在程序或项目的完整执行中只创建类的一个实例。它用于在整个执行过程中只需要一个类的单个实例来控制操作。一个单例类在任何情况下都不应该有多个实例并且不惜任何代价。单例类用于日志记录、驱动程序对象、缓存和线程池、数据库连接。
单例设计模式
单例类的实现
单例类的实现应该具有以下属性:
- 它应该只有一个实例:这是通过从类中提供类的实例来完成的。应防止外部类或子类创建实例。这是通过在Java中将构造函数设为私有来完成的,这样任何类都不能访问构造函数,因此无法实例化它。
- 实例应该是全局可访问的:单例类的实例应该是全局可访问的,以便每个类都可以使用它。在Java,它是通过公开实例的访问说明符来完成的。
//A singleton class should have public visibility
//so that complete application can use
public class GFG {
//static instance of class globally accessible
public static GFG instance = new GFG();
private GFG() {
// private constructor so that class
//cannot be instantiated from outside
//this class
}
}
详细文章:单例设计模式在Java
单例的初始化类型
- 单例类可以通过两种方法实例化:
- 早期初始化:在此方法中,无论是否使用类,都会对其进行初始化。这种方法的主要优点是简单。您在加载类时启动类。它的缺点是类总是被初始化,不管它是否被使用。
- 延迟初始化:在此方法中,类仅在需要时才初始化。当您不需要它时,它可以使您免于实例化该类。一般我们在创建单例类的时候都会用到延迟初始化。
单例类示例
- Java.lang.Runtime : Java在其 lang 包中提供了一个 Runtime 类,它本质上是单例的。每个Java应用程序都有一个 Runtime 类的单个实例,它允许应用程序与应用程序运行的环境进行交互。可以从 getRuntime() 方法获取当前运行时。
应用程序无法实例化此类,因此无法为此类创建多个对象。因此 Runtime 是一个单例类。 - Java.awt.Desktop : Desktop 类允许Java应用程序启动在本机桌面上注册的关联应用程序来处理 URI 或文件。
支持的操作包括:- 启动用户默认浏览器以显示指定的 URI;
使用可选的 mailto URI 启动用户默认邮件客户端; - 启动已注册的应用程序以打开、编辑或打印指定文件。
- 此类提供与这些操作对应的方法。这些方法查找在当前平台上注册的关联应用程序,并启动它以处理 URI 或文件。如果没有关联应用或关联应用启动失败,则抛出异常。
- 每个操作都是由 Desktop.Action 类表示的一种操作类型。
此类也不能从应用程序实例化。因此它也是一个单例类。
- 启动用户默认浏览器以显示指定的 URI;
单例类的应用
有很多单例模式的应用,如缓存、数据库连接、驱动程序、日志记录。其中一些主要是:-
- 硬件接口访问:单例的使用视需求而定。单例类也用于防止类的并发访问。实际上,在需要外部硬件资源使用限制的情况下可以使用单例,例如可以将打印后台处理程序设为单例的硬件打印机,以避免多个并发访问和造成死锁。
- Logger :单例类用于日志文件生成。日志文件由记录器类对象创建。假设一个应用程序,其中日志实用程序必须根据从用户收到的消息生成一个日志文件。如果有多个客户端应用程序使用此日志实用程序类,它们可能会创建此类的多个实例,并且可能会在并发访问同一个记录器文件期间导致问题。我们可以将 logger 实用程序类用作单例,并提供一个全局参考点,以便每个用户都可以使用该实用程序,并且不会有 2 个用户同时访问它。
- 配置文件:这是单例模式的另一个潜在候选者,因为它具有性能优势,因为它可以防止多个用户重复访问和读取配置文件或属性文件。它创建配置文件的单个实例,可以通过多个调用同时访问该实例,因为它将提供加载到内存对象中的静态配置数据。应用程序仅在第一次从配置文件中读取,此后从第二次调用开始,客户端应用程序从内存中的对象读取数据。
- 缓存:我们可以将缓存用作单例对象,因为它可以具有全局引用点,并且对于所有未来对缓存对象的调用,客户端应用程序将使用内存中的对象。
要点
- 单例类只能有一个实例,并且该实例应该是全局可访问的。
- Java.lang.Runtime 和Java.awt.Desktop 是 JVM 提供的 2 个单例类。
- 单例设计模式是一种创建型设计模式。
- 应防止外部类创建单例类的实例。
参考:-
https://en.wikipedia.org/wiki/Singleton_pattern
https://docs.oracle.com/javase/7/docs/api/的Java/lang/Runtime.html
https://docs.oracle.com/javase/7/docs/api/的Java/awt/Desktop.html