单例模式(Singleton Pattern)

动机:

在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。

如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?

这应该是类设计者的责任,而不是使用者的责任。

意图:

保证一个类仅有一个实例,并提供一个该实例的全局访问点。

单线程Singleton模式的几个要点

? Singleton模式中的实例构造器可以设置为protected以允许子类派生。
? Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。
? Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与Singleton模式的初衷违背。
? Singletom模式只考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没有必要对其销毁进行特殊的管理。
? 不能应对多线程环境:在多线程环境下,使用Singleton模式仍然有可能得到Singleton类的多个实例对象。

 1 namespace 单例设计模式
 2 {
 3     public class Singleton
 4     {
 5         //定义一个静态变量
 6         private static Singleton singleton;
 7         public static object obj = new object();
 8 
 9         //定义一个私有的构造函数
10         private Singleton() { }
11 
12         //定义一个静态初始化方法
13         public static Singleton Instance()
14         {
15             if (singleton == null)
16             {
17                 lock (obj)
18                 {
19                     if (singleton == null)
20                     {
21                         singleton = new Singleton();
22                     }
23                 }
24             }
25 
26             return singleton;
27         }
28     }
29 }
30 
31 //针对C#语言特性,单例模式的简单实现方法
32 namespace 单态设计模式
33 {
34     public sealed class Singleton
35     {
36         //定义一个静态变量
37         private static readonly Singleton singleton = new Singleton();
38 
39         //定义一个私有的构造函数
40         private Singleton() { }
41 
42         //定义一个静态初始化方法
43         public static Singleton Instance()
44         {
45             return singleton;
46         }
47     }
48 }
49 
50 //客户端代码
51 namespace 单例设计模式
52 {
53     class Program
54     {
55         static void Main(string[] args)
56         {
57             Singleton s1 = Singleton.Instance();
58             Singleton s2 = Singleton.Instance();
59 
60             if (s1 == s2)
61             {
62                 Console.WriteLine("两个对象相等!");
63             }
64             else
65             {
66                 Console.WriteLine("两个对象不相等!");
67             }
68 
69             Console.ReadKey();
70         }
71     }
72 }
View Code

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。