CSharp面向对象设计模式纵横谈--Singleton Pattern 听课笔记

本文深入探讨了单例模式的设计理念,包括其分类、动机、意图及实现方式。详细讲解了单例模式在单线程和多线程环境下的具体实现,并讨论了模式的限制与扩展可能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

模式分类:

       从目的看:

              创建型(Creational)模式:负责对象创建

              结构型(Structural)模式:处理类与对象间的组合

              行为型(Behavioral)模式:类与对象交互中的职责分配

从范围看:

       类模式处理类与子类的静态关系

       对象模式处理对象间的动态关系

 

动机(Motivation

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

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

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

 

意图(Intent

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

 

单线程Singleton模式实现

 1None.gifPublic class Singleton
 2ExpandedBlockStart.gifContractedBlock.gif       dot.gif{
 3InBlock.gif              Private static Singleton instance;
 4ExpandedSubBlockStart.gifContractedSubBlock.gif              Private Singleton()dot.gif{}
 5InBlock.gif
 6InBlock.gif              Public static Singleton Instance
 7ExpandedSubBlockStart.gifContractedSubBlock.gif              dot.gif{
 8InBlock.gif                     Get
 9ExpandedSubBlockStart.gifContractedSubBlock.gif                     dot.gif{
10InBlock.gif                            If(instance==null)
11ExpandedSubBlockStart.gifContractedSubBlock.gif                            dot.gif{
12InBlock.gif                                   Instance=new Singleton();
13InBlock.gif
14ExpandedSubBlockEnd.gif                            }

15InBlock.gif
16InBlock.gif                            Return instance;
17InBlock.gif
18ExpandedSubBlockEnd.gif                     }

19ExpandedSubBlockEnd.gif              }

20ExpandedBlockEnd.gif       }

21None.gif
22None.gifclass Test
23ExpandedBlockStart.gifContractedBlock.gifdot.gif{
24InBlock.gifpublic static void Main()
25InBlock.gif
26ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
27InBlock.gif
28InBlock.gifSingleton t1=Singleton.Instance;
29InBlock.gif
30InBlock.gifSingleton t2=Singleton.Instance;
31InBlock.gif
32ExpandedSubBlockEnd.gif}

33InBlock.gif
34ExpandedBlockEnd.gif}

35None.gif
36None.gif

 

Exceptions 和 Singleton:

       以上的方式需要每次都来检查Instance是否为空,我们可以创建自己的Exception类来捕捉Instance不为空时的操作。

      

 1None.gif public class SingletionException:Exception
 2None.gif
 3ExpandedBlockStart.gifContractedBlock.gif       dot.gif{
 4InBlock.gif
 5InBlock.gif              Public SingletonException(string s):base(s)
 6InBlock.gif
 7ExpandedSubBlockStart.gifContractedSubBlock.gif              dot.gif{
 8InBlock.gif
 9ExpandedSubBlockEnd.gif              }

10InBlock.gif
11ExpandedBlockEnd.gif       }

12None.gif
13None.gif

Instance不为NULL时抛出异常

None.gifpublic class Singleton
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
InBlock.gif       
private static bool flag_Instance=false;
InBlock.gif
InBlock.gif       
private Singleton()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif       
public static GetSingleton()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif              
if(flag_Instance)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif              
dot.gif{
InBlock.gif
InBlock.gif                     
throw new SingletonException("Only one Instance allowed");
InBlock.gif
ExpandedSubBlockEnd.gif              }

InBlock.gif
InBlock.gif              
else
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif              
dot.gif{
InBlock.gif
InBlock.gif                     flag_Instance
=true;
InBlock.gif
ExpandedSubBlockEnd.gif              }

InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
ExpandedBlockEnd.gif}
;
None.gif
None.gif

 

单线程Singleton模式的几个要点:

1.  Singleton模式中的实例构造器可以设置为Protected以允许子类派生。

2.  Singleton模式一般不要支持IConeable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。

3.  Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与Singleton模式的初衷违背。

4.  Singleton模式只考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾挥手的平台和对象的开销来讲,我们一般没有必要对其进行特殊的管理。

5.  不能应对多线程环境,在多线程环境下,使用Singleton模式仍然有可能得到Singleton类的多个实例对象

 

多线程Singletion模式:

1.使用double-check来完成

 1None.gifclass Singleton
 2None.gif
 3ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 4InBlock.gif
 5InBlock.gif       private static volatile Singleton instance=null;//volatile在编译是不进行微调
 6InBlock.gif
 7InBlock.gif       private static object lockHelper=new Object();
 8InBlock.gif
 9InBlock.gif 
10InBlock.gif
11InBlock.gif       private Singleton()//私有构造器,使得Singleton 只可以在本类的内部被创建
12InBlock.gif
13ExpandedSubBlockStart.gifContractedSubBlock.gif       dot.gif{
14InBlock.gif
15ExpandedSubBlockEnd.gif       }

16InBlock.gif
17InBlock.gif 
18InBlock.gif
19InBlock.gif       public static Singleton Instance
20InBlock.gif
21ExpandedSubBlockStart.gifContractedSubBlock.gif       dot.gif{
22InBlock.gif
23InBlock.gif              get
24InBlock.gif
25ExpandedSubBlockStart.gifContractedSubBlock.gif              dot.gif{
26InBlock.gif
27InBlock.gif                     if(instance==null)
28InBlock.gif
29ExpandedSubBlockStart.gifContractedSubBlock.gif                     dot.gif{
30InBlock.gif
31InBlock.gif                            lock(lockHelper)
32InBlock.gif
33ExpandedSubBlockStart.gifContractedSubBlock.gif                            dot.gif{
34InBlock.gif
35InBlock.gif                                   if(instance==null)//避免了两个线程产生两个实例的危险
36InBlock.gif
37ExpandedSubBlockStart.gifContractedSubBlock.gif                                   dot.gif{
38InBlock.gif
39InBlock.gif                                          instance=new Singleton();
40InBlock.gif
41ExpandedSubBlockEnd.gif                                   }

42InBlock.gif
43ExpandedSubBlockEnd.gif                            }

44InBlock.gif
45ExpandedSubBlockEnd.gif                     }

46InBlock.gif
47InBlock.gif 
48InBlock.gif
49InBlock.gif                     return instance;
50InBlock.gif
51ExpandedSubBlockEnd.gif              }

52InBlock.gif
53ExpandedSubBlockEnd.gif       }

54InBlock.gif
55ExpandedBlockEnd.gif}
;
56None.gif
57None.gif

2.多线程Singleton Pattern的一种更好的方式:

 1None.gifclass Singleton
 2None.gif
 3ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 4InBlock.gif
 5InBlock.gif       public static readonly Singleton Instance=new Singleton();
 6InBlock.gif
 7InBlock.gif       private Singleton()
 8InBlock.gif
 9ExpandedSubBlockStart.gifContractedSubBlock.gif       dot.gif{
10InBlock.gif
11ExpandedSubBlockEnd.gif       }

12InBlock.gif
13ExpandedBlockEnd.gif}
;
14None.gif
15None.gif

 

3.上述代码等同于:

 1None.gifclass Singleton
 2None.gif
 3ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 4InBlock.gif
 5InBlock.gif       public static readonly Singleton Instance;
 6InBlock.gif
 7InBlock.gif 
 8InBlock.gif
 9InBlock.gif       static Singleton()
10InBlock.gif
11ExpandedSubBlockStart.gifContractedSubBlock.gif       dot.gif{
12InBlock.gif
13InBlock.gif              Instance =new Singleton();
14InBlock.gif
15ExpandedSubBlockEnd.gif       }

16InBlock.gif
17InBlock.gif 
18InBlock.gif
19InBlock.gif       private Singleton()
20InBlock.gif
21ExpandedSubBlockStart.gifContractedSubBlock.gif       dot.gif{
22InBlock.gif
23ExpandedSubBlockEnd.gif       }

24InBlock.gif
25ExpandedBlockEnd.gif}
;
26None.gif
27None.gif

 

 

Singleton模式扩展:

1.  将一个实例扩展到N个实例,例如对象池的实现。(N是固定的)。

2.  将new构造器的调用转移到其他类中,例如多个类协同工作环境中,某个局部环境只需要拥有某个类的一个实例。

3.  理解和扩展SINGLETON模式的核心是“如何控制用户使用new对一个类的实例构造器的任意调用“。

转载于:https://www.cnblogs.com/leib_0474/archive/2005/10/25/261954.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值