设计模式之单例模式

定义:对于一个软件系统的某些类而言,我们无须创建多个实例。为了节约系统资源,有时需要确保系统中某个类只有唯一一个实例,当这个唯一实例创建成功之后,我们无法再创建一个同类型的其他对象,所有的操作都只能基于这个唯一实例。为了确保对象的唯一性,我们可以通过单例模式来实现,这就是单例模式的需求所在。

优点:
-单例模式提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。

  • 由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
    -允许可变数目的实例。基于单例模式我们可以进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例,既节省系统资源,又解决了单例单例对象共享过多有损性能的问题。

缺点:

  • 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
  • 单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。
    -现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的共享对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致共享的单例对象状态的丢失。

应用:
1.懒汉式

1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton
{
private staticSingleton _insance = null;
private Singleton() {……} //
public static Singleton getInstance()
{
if (_insance == null)
{
_insance = new Singleton();
}
return _insance;
}
}

2.饿汉士:由于懒汉式_insance = new XXX();需要一定时间,当new未完成时调用会出现两个实例化,这就不满足单例模式了,以下写法在系统加载时由于需要创建单例对象,加载时间可能会比较长。

1
2
3
4
5
6
7
8
9
class Singleton
{
private static Singleton _insance = new Singleton();
private Singleton() {……} //
public static Singleton getInstance()
{
return _insance;
}
}

3.考虑多线程情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Singleton {  

private volatile static Singleton singleton;

private Singleton (){}

public static Singleton getSingleton() {

if (singleton == null) {

synchronized (Singleton.class) {

if (singleton == null) {

singleton = new Singleton();

}

}

}

return singleton;

}
}
}