从生活中的点点滴滴认识设计模式系列(三)

单件模式(Singleton Pattern)


“老樊,你这次去山西出差得多久啊?”小刘在电话那头说。

“呃……这回我过来手头上兼着三个项目,估计得有段时间啊!你不知道来山西这几天我有多累啊,写文档写到手都要抽筋了!”

“那你可得注意休息啊,上次你给我说的那两个设计模式我已经很熟练了,你啥时候教我新的设计模式啊?”

“这样吧,等我把手头上的这个需求分析写完,我就给你电话。”

 

写文档时间过得很快,一转眼就到深夜了。

酒店很安静,但是我的思绪却清晰不起来,用户需求中有一部分始终不能很好的理解,也许是想了一天,大脑零件也该断电休息休息了。

躺在床上怎么也睡不着,老觉得有件事情还没做,仔细想想才记起今天答应给小刘讲设计模式了。

发条短信过去试探试探看看她睡没,“小刘,你睡了没”。

很快就收到了回复,这家伙还没睡啊。

“还没呢,一直在等你电话呢,我可不象某人说话不算话啊!”

赶紧拨通了电话。

“呃……小刘,不好意思啊,忙晕头了!”

“嗯!没事,今天咱们讲什么设计模式啊?”

“今天这么晚了,就讲一个简单的设计模式-单件模式吧!”

“嗯!这个我明白,这个模式的意思就是保证一个对象的唯一性吧!”

“对,单件模式就是保证一个对象独一无二,就象你身上的器官一样,都是独一无二的,别人肯定没有小刘的左眼或者小刘的右眼吧!”

“嗯,这个模式很好理解!”

“一会我把例子写出来给你发过去,你早点休息吧!”

“好的,你要是累了就早点休息,明天再给我也是一样!ByeBye!”

 

单件模式UML图:

模式人生-从生活中的点点滴滴认识设计模式3-单件模式(Singleton Pattern)

instance:Singlegon的实例。

Singleton():私有的构造函数。

GetSinglegon():返回Singleton对象instance。

 

单例模式代码:

LiuRightHand.cs

System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SingletonPattern { /// <summary> /// 小刘右手 /// </summary> public class LiuRightHand { //私有静态小刘右手对象 private static LiuRightHand instance = null; //私有构造函数 private LiuRightHand() { } //公用属性,获得小刘右手对象 public static LiuRightHand GetRightHand() { if (instance == null) { instance = new LiuRightHand(); } return instance; } } }

 

 

这样并不能保证该类的唯一性,在多线程程序中可能会产生多个小刘右手实例,这样小刘不就成了多臂怪啦。

因此需要解决多线程下可能产生多个实例的问题:

 

LiuLeftHand.cs

 

System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SingletonPattern { /// <summary> /// 小刘左手 /// </summary> public class LiuLeftHand { //私有静态小刘左手对象 private static LiuLeftHand instance = null; public static readonly object handLock = new object(); //私有构造函数 private LiuLeftHand() { } //公用方法,获得小刘左手对象 public static LiuLeftHand GetLeftHand() { lock (handLock) { if (instance == null) { instance = new LiuLeftHand(); } return instance; } } } }

 

 

在一个线程使用该对象时,lock方法将会锁住代码,另一个线程如果要使用该对象,会一直等待,直到前一个线程使用完。

 

我们还可以对代码进行优化。

双重锁定:

LiuRightFoot.cs

System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SingletonPattern { /// <summary> /// 小刘右脚 /// </summary> public class LiuRightFoot { //私有静态小刘右脚对象 private static LiuRightFoot instance = null; public static readonly object footLock = new object(); //私有构造函数 private LiuRightFoot() { } //公用属性,获得小刘右脚对象 public static LiuRightFoot GetRightHand() { if (instance == null) { lock (footLock) { if (instance == null) { instance = new LiuRightFoot(); } } } return instance; } } }

 

静态初始化:

LiuLeftFoot.cs

System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SingletonPattern { /// <summary> /// 小刘左脚 /// </summary> public sealed class LiuLeftFoot { //私有静态小刘左脚对象 private static readonly LiuLeftFoot instance = new LiuLeftFoot(); //私有构造函数 private LiuLeftFoot() { } //公用方法,获得小刘左脚对象 public static LiuLeftFoot GetLeftHand() { return instance; } } }

 

再来对单件模式进行一下总结:

1. 单件模式就是保证一个对象有且只有一个实例,并且提供了一个全局的访问点。

2. 单件模式在多线程编程时可以利用双重锁定和静态初始化保证唯一性。

 

使用场景:

1. 当一个对象需要独一无二时。

 

写了这么多,这回可真要手抽筋了。

明天就双休了,可惜双休没得休啊,还得继续写文档。

文章源代码:
下载

从生活中的点点滴滴认识设计模式系列文章:

1. 从生活中的点点滴滴认识设计模式1-装饰器模式(Decorator Pattern)
2. 从生活中的点点滴滴认识设计模式2-策略模式(Strategy Patten)
3. 从生活中的点点滴滴认识设计模式3-单件模式(Singlegon Patten)

相关文章: