单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
单例模式同时解决了两个问题, 所以违反了单一职责原则:
- 保证一个类只有一个实例。 为什么会有人想要控制一个类所拥有的实例数量? 最常见的原因是控制某些共享资源 (例如数据库或文件) 的访问权限。
- 为该实例提供一个全局访问节点。
创建方式:
- 将默认构造设置为私有构造函数,防止其他对象使用单例类的new运算符
- 创建一个静态构建方法作为构造函数
如果你的代码能够访问单例类, 那它就能调用单例类的静态方法。 无论何时调用该方法, 它总是会返回相同的对象。
而现实世界中这样例子有很多,譬如:世界上只有一个独一无二的你,一个国家只有而且唯一的官方政府等。
单例模型结构:
上代码:
基础单例(单线程)
实现一个粗糙的单例非常简单。 你仅需隐藏构造函数并实现一个静态的构建方法即可(线程不安全)。
public final class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
第二种:
public final class Singleton {private static Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {synchronized(Singleton.class){if (instance == null) {instance = new Singleton();}return instance;}}
}
第三种:
public final class Singleton {private Singleton() {}private static class M {private final static Singleton instance = new Singleton();}public static Singleton getInstance(){return M.instance;}}
在java核心库中的使用:
尽管如此, Java 核心程序库中仍有相当多的单例示例:
- java.lang.Runtime#getRuntime()
- java.awt.Desktop#getDesktop()
- java.lang.System#getSecurityManager()
单例模式适合应用场景
如果程序中的某个类对于所有客户端只有一个可用的实例, 可以使用单例模式。
单例模式禁止通过除特殊构建方法以外的任何方式来创建自身类的对象。 该方法可以创建一个新对象, 但如果该对象已经被创建, 则返回已有的对象。
如果你需要更加严格地控制全局变量, 可以使用单例模式。
单例模式与全局变量不同, 它保证类只存在一个实例。 除了单例类自己以外, 无法通过任何方式替换缓存的实例。
请注意, 你可以随时调整限制并设定生成单例实例的数量, 只需修改 获取实例
方法, 即 getInstance 中的代码即可实现。