设计模式探秘-4-单例模式

单例模式

单例模式定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供该实例。

单例模式优点:

  1. 单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁创建、销毁,而且创建或销毁时性能又无法优化时,单例模式的优势非常明显。
  2. 单例模式只生产一个实例,减少了系统的性能开销,当一个对象的产生需要比较多的资源时,则可以通过在应用启动时直接生产一个单例对象,然后永久驻留在内存中的方式来解决。
  3. 单例模式可以避免对资源的多重访问。
  4. 单例模式可以在系统设置全局的访问点,优化和共享资源访问。

单例模式缺点:

  1. 单例模式一般没有接口,扩展困难。因为接口对于单例模式没有意义,单例模式“自行实例化”,并且提供单一实例,接口和抽象类是不可能被实例化的。但特殊情况下单例模式可以实现接口、被继承等。
  2. 单例模式对测试不利。并行开发环境中,单例模式未完成前,不能进行测试,没有接口也就无法虚拟对象。
  3. 单例模式与单一职责原则有冲突。单例模式把“要单例”和业务逻辑融合在一个类中。

单例模式使用场景

在一个系统中,如果要求有且仅有一个对象,如果出现多个会有不良反应,就可以使用单例模式。

  1. 要求生成唯一化序列号的环境。
  2. 在整个项目中需要一个共享访问点或共享数据。
  3. 创建一个对象需要消耗的资源过多。
  4. 需要定义大量静态方法或静态变量的环境,可以采用单例模式。

单例模式和全局变量

  1. 全局变量不能防止实例化多个对象。
  2. 使用全局变量将使对象无论是否被用到都要被创建。

单例模式的实现

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <iostream>

using namespace std;

//常见的单例模式
class SingletonOne
{
private:
SingletonOne()
{
cout<<__FUNCTION__<<endl;
}
SingletonOne(const SingletonOne &right);
SingletonOne & operator=(const SingletonOne &right);
static SingletonOne _instance;
public:
static SingletonOne& Instance()
{
return _instance;
};
~SingletonOne()
{
cout<<__FUNCTION__<<endl;
}
void print()
{
cout<<__FUNCTION__<<endl;
};
};
SingletonOne SingletonOne::_instance;

class SingletonTwo
{
private:
SingletonTwo()
{
cout<<__FUNCTION__<<endl;
}
SingletonTwo(const SingletonTwo &right);
SingletonTwo & operator=(const SingletonTwo &right);
static SingletonTwo *_instance;
public:
static SingletonTwo* Instance()
{
if( nullptr == _instance )
{
_instance = new SingletonTwo();
}
return _instance;
};
~SingletonTwo()
{
cout<<__FUNCTION__<<endl;
}
void print()
{
cout<<__FUNCTION__<<endl;
};
};
SingletonTwo* SingletonTwo::_instance = nullptr;

template <class T>
class SingletonThree
{
private:
SingletonThree(){}
SingletonThree(const SingletonThree &right);
SingletonThree & operator=(const SingletonThree &right);
static T _instance;
public:
static T& Instance()
{
return _instance;
};
virtual ~SingletonThree(){}
};

template <class T>
T SingletonThree<T>::_instance;

class A
{
public:
A()
{
cout<<__FUNCTION__<<endl;
}
virtual ~A()
{
cout<<__FUNCTION__<<endl;
}
void print()
{
cout<<__FUNCTION__<<endl;
}
};
typedef SingletonThree<A> SingletonA; //SingletonA

int main()
{
//SingletonOne::Instance().print();
//SingletonTwo::Instance()->print();
SingletonA::Instance().print();
return 0;
}

参考资料

  1. 设计模式之禅
  2. GoF+23种设计模式解析