单件型模式(Singleton Pattern)
概述
Singleton模式要求一个类有且仅有一个实例,并且提供了一个全局的访问点。这就提出了一个问题:如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?客户程序在调用某一个类时,它是不会考虑这个类是否只能有一个实例等问题的,所以,这应该是类设计者的责任,而不是类使用者的责任。
意图
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
例子
1.ASP.NET某应用程序对应的Application必须是唯一的。
2.不管在什么时候谈到地球,它都是指同一个地球。
3.某全局计数器对象是必须是唯一的,否则会使计数失败。
UML类图

代码:对应UML类图
1
/// <summary>
2
/// UML类图对应单件类
3
/// </summary>
4
public class Singleton
5
{
6
private static Singleton instance;
7
8
private Singleton() { }
9
10
public static Singleton Instance
11
{
12
get
13
{
14
if (instance == null)
15
{
16
instance = new Singleton();
17
}
18
return instance;
19
}
20
}
21
}
/// <summary>2
/// UML类图对应单件类3
/// </summary>4
public class Singleton5
{6
private static Singleton instance;7

8
private Singleton() { }9

10
public static Singleton Instance11
{12
get13
{14
if (instance == null)15
{16
instance = new Singleton();17
}18
return instance;19
}20
}21
} 1
/// <summary>
2
/// UML类图对应客户端程序类
3
/// </summary>
4
public class MainApp
5
{
6
public static void Main()
7
{
8
Singleton s1 = Singleton.Instance;
9
Singleton s2 = Singleton.Instance;
10
11
if (s1 == s2)
12
{
13
Console.WriteLine("Object are the same instance");
14
}
15
16
Console.Read();
17
}
18
}
/// <summary>2
/// UML类图对应客户端程序类3
/// </summary>4
public class MainApp5
{6
public static void Main()7
{8
Singleton s1 = Singleton.Instance;9
Singleton s2 = Singleton.Instance;10

11
if (s1 == s2)12
{13
Console.WriteLine("Object are the same instance");14
}15

16
Console.Read();17
}18
}代码:六种实现方式
1.最简单的实现,但不支持线程安全
1
/// <summary>
2
/// 最简单的单件模式
3
/// 不支持多线程安全
4
/// </summary>
5
public class Singleton1
6
{
7
private Singleton1() { }
8
9
private Singleton1 instance = null;
10
11
public Singleton1 Instance
12
{
13
get
14
{
15
if (this.instance == null)
16
{
17
this.instance = new Singleton1();
18
}
19
return this.instance;
20
}
21
}
22
}
/// <summary>2
/// 最简单的单件模式3
/// 不支持多线程安全4
/// </summary>5
public class Singleton16
{7
private Singleton1() { }8

9
private Singleton1 instance = null;10

11
public Singleton1 Instance12
{13
get14
{15
if (this.instance == null)16
{17
this.instance = new Singleton1();18
}19
return this.instance;20
}21
}22
}2.支持线程安全,但是不支持多线程的并发操作
1
/// <summary>
2
/// 线程安全
3
/// 但不支持线程并发
4
/// </summary>
5
public class Singleton2
6
{
7
private Singleton2() { }
8
9
private Singleton2 instance = null;
10
11
private static object objLock = new object();
12
13
public Singleton2 Instance
14
{
15
get
16
{
17
lock (objLock)
18
{
19
if (this.instance == null)
20
{
21
this.instance = new Singleton2();
22
}
23
}
24
return this.instance;
25
}
26
}
27
}
/// <summary>2
/// 线程安全3
/// 但不支持线程并发4
/// </summary>5
public class Singleton26
{7
private Singleton2() { }8

9
private Singleton2 instance = null;10

11
private static object objLock = new object();12

13
public Singleton2 Instance14
{15
get16
{17
lock (objLock)18
{19
if (this.instance == null)20
{21
this.instance = new Singleton2();22
}23
}24
return this.instance;25
}26
}27
}3.支持线程安全,使用双检查(Double Check),支持多线程的并发操作
1
/// <summary>
2
/// 线程安全
3
/// 支持线程并发
4
/// </summary>
5
public class Singleton3
6
{
7
private Singleton3 instance = null;
8
9
private Singleton3() { }
10
11
private static object objLock = null;
12
13
public Singleton3 Instance
14
{
15
get
16
{
17
if (this.instance == null)
18
{
19
lock (objLock)
20
{
21
if (this.instance == null)
22
{
23
this.instance = new Singleton3();
24
}
25
}
26
}
27
return this.instance;
28
}
29
}
30
31
}
/// <summary>2
/// 线程安全3
/// 支持线程并发4
/// </summary>5
public class Singleton36
{7
private Singleton3 instance = null;8

9
private Singleton3() { }10

11
private static object objLock = null;12

13
public Singleton3 Instance14
{15
get16
{17
if (this.instance == null)18
{19
lock (objLock)20
{21
if (this.instance == null)22
{23
this.instance = new Singleton3();24
}25
}26
}27
return this.instance;28
}29
}30

31
}4.使用静态初始化方式,但不支持缓实例化
1
/// <summary>
2
/// 静态初始化
3
/// 但不实现缓初始化
4
/// </summary>
5
public class Singleton4
6
{
7
private Singleton4() { }
8
9
private readonly static Singleton4 Instance = new Singleton4();
10
}
/// <summary>2
/// 静态初始化3
/// 但不实现缓初始化4
/// </summary>5
public class Singleton46
{7
private Singleton4() { }8

9
private readonly static Singleton4 Instance = new Singleton4();10
}5.使用静态初始化方式,且支持缓实例化,但引入了附加类
1
/// <summary>
2
/// 静态初始化
3
/// 实现缓初始化
4
/// </summary>
5
public class Singleton5
6
{
7
private Singleton5() { }
8
9
public static Singleton5 Instance
10
{
11
get
12
{
13
return Nested.instance;
14
}
15
}
16
17
class Nested
18
{
19
private Nested() { }
20
21
internal readonly static Singleton5 instance = new Singleton5();
22
}
23
}
24
/// <summary>2
/// 静态初始化3
/// 实现缓初始化4
/// </summary>5
public class Singleton56
{7
private Singleton5() { }8

9
public static Singleton5 Instance10
{11
get12
{13
return Nested.instance;14
}15
}16

17
class Nested18
{19
private Nested() { }20

21
internal readonly static Singleton5 instance = new Singleton5();22
}23
}24

6.使用静态初始化方式,且支持缓实例化,实际使用时首选
1
/// <summary>
2
/// 静态实例
3
/// 实现缓初始化
4
/// .NET下的首选方式
5
/// </summary>
6
public class Singleton6
7
{
8
private static Singleton6 instance;
9
10
private Singleton6() { }
11
12
public static Singleton6 Instance
13
{
14
get
15
{
16
if (Singleton6.instance == null)
17
{
18
Singleton6.instance = new Singleton6();
19
}
20
return instance;
21
}
22
}
23
}
/// <summary>2
/// 静态实例3
/// 实现缓初始化4
/// .NET下的首选方式5
/// </summary>6
public class Singleton67
{8
private static Singleton6 instance;9

10
private Singleton6() { }11

12
public static Singleton6 Instance13
{14
get15
{16
if (Singleton6.instance == null)17
{18
Singleton6.instance = new Singleton6();19
}20
return instance;21
} 22
}23
}代码:完整例子
实现简单计数功能
1
/// <summary>
2
/// 计数器类
3
/// </summary>
4
public class SingletonCounter
5
{
6
/// <summary>
7
/// 将构造函数置为私有
8
/// </summary>
9
private SingletonCounter() { }
10
11
private static SingletonCounter instance;
12
13
public static SingletonCounter Instance
14
{
15
get
16
{
17
// 缓实例化
18
if (instance == null)
19
{
20
instance = new SingletonCounter();
21
}
22
return instance;
23
}
24
}
25
26
// 存放计数结构
27
private int num = 0;
28
29
// 计数
30
public void Add()
31
{
32
this.num++;
33
}
34
35
// 获取计数结果
36
public int GetNum()
37
{
38
return this.num;
39
}
40
}
/// <summary>2
/// 计数器类3
/// </summary>4
public class SingletonCounter5
{6
/// <summary>7
/// 将构造函数置为私有8
/// </summary>9
private SingletonCounter() { }10

11
private static SingletonCounter instance;12

13
public static SingletonCounter Instance14
{15
get16
{17
// 缓实例化18
if (instance == null)19
{20
instance = new SingletonCounter();21
}22
return instance;23
}24
}25

26
// 存放计数结构27
private int num = 0;28

29
// 计数30
public void Add()31
{32
this.num++;33
}34

35
// 获取计数结果36
public int GetNum()37
{38
return this.num;39
}40
} 1
/// <summary>
2
/// 执行计数类
3
/// </summary>
4
public class DoCounter
5
{
6
public void Counter()
7
{
8
SingletonCounter sc;
9
10
for (int i = 0; i < 10; i++)
11
{
12
// 每次使用到计数器对象都重新赋值
13
sc = SingletonCounter.Instance;
14
sc.Add();
15
Console.WriteLine(sc.GetNum());
16
}
17
}
18
}
/// <summary>2
/// 执行计数类3
/// </summary>4
public class DoCounter5
{6
public void Counter()7
{8
SingletonCounter sc;9

10
for (int i = 0; i < 10; i++)11
{12
// 每次使用到计数器对象都重新赋值13
sc = SingletonCounter.Instance;14
sc.Add();15
Console.WriteLine(sc.GetNum());16
}17
}18
} 1
/// <summary>
2
/// 客户端
3
/// </summary>
4
public class MyApp
5
{
6
public static void Main()
7
{
8
DoCounter dc = new DoCounter();
9
dc.Counter();
10
11
Console.Read();
12
}
13
}
/// <summary>2
/// 客户端3
/// </summary>4
public class MyApp5
{6
public static void Main()7
{8
DoCounter dc = new DoCounter();9
dc.Counter();10

11
Console.Read();12
}13
}总结
单件模式提供非常好的机制保证,实例唯一且有全局唯一访问点。
源代码:[下载]
参考
1. 【dofactory】ttp://www.dofactory.com/Patterns/Patterns.aspx#list
2. 【Terrylee】http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html
3. 【卢振宇老师】http://zhenyulu.cnblogs.com/category/6930.html



浙公网安备 33010602011771号