一、情人节的故事
2015年8月20日情人节这天,我亲眼见了一场“疯狂的战斗”,里面的主人公是一位帅哥(这里暂且称小A),我走在去学校的路上,途径一个高档餐厅,当我矗立在餐厅窗户边的时候,看到里面有一对情侣在里面一起吃饭甚是浪漫,突然黑色的乌云笼罩了天空,我顺着乌云的方向透过明亮的窗户,看到了三个美女一起将那对情侣保卫了起来,这个时候小A想要溜走,此时却被三个美女一起抓住,只听里面说到:“你不是没时间和我过情人节吗?这个人是谁?”,此时小A对面的美女站起来就说:“我是他女朋友,你们是谁啊?”,这时三位美女又说:“我是他好了两年的女朋友,他一直说只有我一个人,怎么你就成了他女朋友了?”,后来血腥的场面就不给大家细说大家也知道了吧,最后四位美女一起关爱了小A一番都扬长而去了,此时我叹息道:“小A啊,只怪你不懂得运用单例模式啊!虽然找几个女朋友是你自己来决定,但是如果你找的超过一个之后,她们有一天见面了,后果...”
二、定义
要点:
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
具体实现:
1.单例模式的类只提供私有的构造函数
2.类定义中含有一个该类的静态私有对象
3.该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象
三、UML图
四、C#代码实例
客户端调用代码
<span style="font-family:KaiTi_GB2312;font-size:18px;"> static void Main(string[] args) { Singleton s1 = Singleton.GetInstance(); Singleton s2 = Singleton.GetInstance(); //比较两个实例化后对象的结果是相同实例 if (s1 == s2 ) { Console.WriteLine("两个对象是相同的实例"); } Console.Read(); }</span>
懒汉式
<span style="font-family:KaiTi_GB2312;font-size:18px;"> class Singleton { private static Singleton instance; //构造方法让其Private,这就堵死了外界利用new创建此类实例的可能 private Singleton() { } //此方法是获得本类实例的唯一全局访问点 public static Singleton GetInstance() { //若实例不存在,则new一个新实例,否则返回已有的实例 if (instance == null ) { instance = new Singleton(); } } }</span>
饿汉式
<span style="font-family:KaiTi_GB2312;font-size:18px;">class Singleton { private static Singleton instance = new Singleton(); //构造方法让其Private,这就堵死了外界利用new创建此类实例的可能 private Singleton() { } //此方法是获得本类实例的唯一全局访问点 public static Singleton GetInstance() { //上面已经实例化过了,所以这里直接返回就可以 return instance; } }</span>
多线程
<span style="font-family:KaiTi_GB2312;font-size:18px;">class Singleton { private static Singleton instance; //程序运行时创建一个静态只读的进程扶助对象 private static readonly object syncRoot = new object(); //构造方法让其Private,这就堵死了外界利用new创建此类实例的可能 private Singleton() { } //此方法是获得本类实例的唯一全局访问点 public static Singleton GetInstance() { //在同一个时刻加了锁的那部分程序只有一个线程可以进入 lock (syncRoot) { //若实例不存在,则new一个新实例,否则返回已有的实例 if (instance == null) { instance = new Singleton(); } } return instance; } }</span>
双重锁
<span style="font-family:KaiTi_GB2312;font-size:18px;"> class Singleton { private static Singleton instance; //程序运行时创建一个静态只读的进程扶助对象 private static readonly object syncRoot = new object(); //构造方法让其Private,这就堵死了外界利用new创建此类实例的可能 private Singleton() { } //此方法是获得本类实例的唯一全局访问点 public static Singleton GetInstance() { //先判断实例是否存在,不存在再加锁处理 if (instance == null) { //在同一个时刻加了锁的那部分程序只有一个线程可以进入 lock (syncRoot) { //若实例不存在,则new一个新实例,否则返回已有的实例 if (instance == null) { instance = new Singleton(); } } } return instance; } }</span>
五、单例优缺点
优点:实例控制(单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例)、灵活(因为类控制了实例化过程,所以类可以灵活更改实例化过程、并且很多地方都不需要再进行实例化)
缺点:可以单击此链接查看: 滥用的单例模式有多少害处
六、感受
再次学习单例模式之后对于它的理解、运用更加深入了,在以后的编程路上需要适度运用单例模式。