1 概念
在软件工程中,单例模式是一种软件设计模式,它将类的实例化限制为一个单一对象。 当需要唯一一个对象来协调系统中的动作时,这种模式非常有用。 此概念有时被泛化到当只有一个对象存在时操作效率更高,或者限制了对象具体数目的系统,单例模式术语来自于数学中单例的概念。
有些人对单例模式持批评态度,认为它是一种反模式(anti-pattern),因为它经常被用于并不适用的场合,这些场合并不要求唯一实例,单例模式的使用因此引入了不必要的限制,并且将全局状态引入到了应用程序中。
单例设计模式是二十三个著名的“四人帮”设计模式之一,描述了如何解决重复出现的设计问题,以设计灵活且可重用的面向对象软件,易于实现、修改、测试以及重用。
单例模式是Java中最简单的设计模式之一。 这种类型的设计模式属于创建型模式,因为此模式提供了创建对象的最佳方法之一。
这种模式涉及一个单独的类,它负责创建一个对象,同时确保只有单个对象被创建。 这个类提供了一种访问其唯一可以直接访问的对象的方法,而无需实例化类的对象。
单例设计模式能够解决类似如下问题:
- 如何确保一个班级只有一个实例?
- 如何轻松访问一个类的唯一实例?
- 一个类如何控制它的实例化?
- 如何限制一个类的实例的数量?
单例设计模式描述了如何解决这些问题:
- 隐藏类的构造函数。
- 定义一个公共静态操作(
getInstance()
),该操作返回该类的唯一实例。
单例模式的核心思想是让类自己负责控制其实例化(即它仅会被实例化一次)。
隐藏的构造函数(声明为private
)确保该类永远不能从类外部被实例化。
通过使用类名称和操作名称(Singleton.getInstance()
)可以轻松访问公共静态操作。
2 实现
单例模式的实现必须:
1. 确保只存在单例类的一个实例;
2. 并提供对该实例的全局访问权限。
通常,这是通过以下方式完成的:
1. 声明该类的所有构造函数均为private
;
2. 并提供一个返回实例引用的静态方法。
实例通常存储为私有静态变量; 当变量被初始化,且在静态方法第一次被调用之前的某个时刻,实例被创建。
2.1 以下是Java的示例实现。
public final class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
2.2 Java Demo
我们将创建一个SingleObject
类。 SingleObject
类的构造函数是私有的,并且具有它自己的静态实例。
SingleObject
类提供了一种静态方法来将其静态实例传递给外部世界。 我们的演示类SingletonPatternDemo
将使用SingleObject
类来获得SingleObject
对象。
2.2.1 第1步 创建一个单例类:
//SingleObject.java
public class SingleObject {
//create an object of SingleObject
private static SingleObject instance = new SingleObject();
//make the constructor private so that this class cannot be
//instantiated
private SingleObject(){}
//Get the only object available
public static SingleObject getInstance(){
return instance;
}
public void showMessage(){
System.out.println("Hello World!");
}
}
2.2.2 第2步 获取单例类的唯一对象
//SingletonPatternDemo.java
public class SingletonPatternDemo {
public static void main(String[] args) {
//illegal construct
//Compile Time Error: The constructor SingleObject() is not visible
//SingleObject object = new SingleObject();
//Get the only object available
SingleObject object = SingleObject.getInstance();
//show the message
object.showMessage();
}
}
2.2.3 第3步 验证输出
Hello World!
3 单例模式的一般使用场合
abstract factory
,builder
, andprototype
模式可在他们的实现中使用单例。Facade
对象由于只需要一个facade对象,因此通常是单例。State
对象经常是单例。- 单例通常比全局变量更受欢迎,因为:
- 它们不会用不必要的变量污染全局名称空间(或者具有名称空间的语言所包含的名称空间)。
- 它们允许延迟分配和初始化,而许多语言的全局变量总是会消耗资源。
(tutorialspoint上列举了35种设计模式。)
[1]https://www.tutorialspoint.com/design_pattern/singleton_pattern.htm
[2]https://en.wikipedia.org/wiki/Singleton_pattern