Singleton模式
应用场景
- 在一个系统要求一个类只有一个实例时才应当使用单例模式。
- 反过来,如果一个类可以有几个实例共存,就不要使用单例模式。
本质
- 控制实例数目
优点
- 在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就防止其它对象对自己的实例化,确保所有的对象都访问一个实例 (私有构造函数)
- 单例模式具有一定的伸缩性。类通过自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。
- 提供了对唯一实例的受控访问。
- 由于在系统内存中只存在一个对象,因此可以节约系统资源,当需要频繁创建和销毁的对象时,单例模式无疑可以提高系统的性能。
- 允许可变数目的实例。
- 避免对共享资源的多重占用。
缺点
- 不适用于变化的对象,如果同一类型的对象总是要在不同的实例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。
- 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
- 单例类的职责过重,在一定程度上违背了“单一职责原则”。
- 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。
角色
- Singleton(单例)
有一个返回唯一实例的static方法
设计模式的类图
示例程序
示例程序的类图
示例代码
单例类:
public class Singleton {
private static Singleton instance;
//private static Singleton instance=new Singleton();
private Singleton() {}
public static Singleton GetInstance() {
if(instance==null) {
instance=new Singleton();
}
return instance;
}
}
客户端:
public class Main {
public static void main(String[] args) {
Singleton singleton1=Singleton.GetInstance();
Singleton singleton2=Singleton.GetInstance();
if(singleton1==singleton2) {
System.out.println("实例相同");
}
}
}
拓展思路
- 当实例数量增加时,可用集合、链表、范式等,但可能会出现bug
- 生成实例时,不适用关键字new,而是调用Singleton.GetInstance()
相关设计模式
- AbstractFactory模式
- Builder模式
- Facade模式
- Prototype模式
满足的原则
- 迪米特法则