1. 单例模式定义
Singleton Pattern:Ensure a class has only one instance, and provide a global point of access to it.( 确保某一个类只有一个实例, 而且自行实例化并向整个系统提供这个实例。 )
- 通用类图如下:
Singleton类为单例类,通过使用private的构造函数,确保了只能在本类中进行实例化操作,而对实例化的时机不同,又可细分为懒汉式和饿汉式单例。
懒汉式:在调用getSingleton()方法时,才进行实例化操作。
public class Singleton {
private static Singleton singleton;
private Singleton() {
// do something
}
public staic Singleton getSinleton() {
if (null == singleton) {
singleton = new Singleton();
}
return singleton;
}
}
- 饿汉式:在声明Singleton类型的变量时,就进行实例化操作
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() {
// do something
}
public staic Singleton getSinleton() {
return singleton;
}
}
2. 单例模式应用
2.1 单例模式优点
- 内存只有一个实例,减少内存开支(尤其是一个对象需要频繁创建、销毁的时候。)
2.2 单例模式缺点
- 一般没有接口,扩展困难。(一般需要修改该类代码)
- 对测试不利
- 与单一职责原则冲突。
2.3 单例模式使用场景
单例模式适用于要求一个类有且只有一个对象,如果出现多个对象就会出现不良反应
- 要求生成唯一序列号的环境
- 在整个项目中,需要一个共享访问点或共享数据。(Web界面的计数器)
- 创建一个对象需要消耗的资源过多(访问IO和数据库等资源)
- 需要定义大量的静态方法和静态常量的环境
2.4 单例模式注意事项
- 高并发情况下,请注意单例模式的线程同步问题。
- 使用饿汉式创建单例不会出现产生多个实例的情况,但是懒汉式就需要考虑线程同步问题。
- 对象克隆情况
- 若一个类实现了Cloneable接口,并实现了clone方法,则可以通过对象复制方式,创建一个新对象。
- 对象复制是不用调用类的构造函数的,即使是私有的构造函数,对象仍可以被复制。
3. 单例模式扩展——多例模式
- 要求一个类只能产生两三个对象。
多例情况类图如下:
4. 最佳实践
- Spring中,每个Bean默认都是单例的
- Spring容器可以管理这些Bean的生命期,决定什么时候创建,什么时候销毁,销毁的时候如何处理。
5. 参考资料
- 大话设计模式
- 设计模式之禅