设计模式之单例模式

来源:互联网 发布:今天淘宝登录不上去 编辑:程序博客网 时间:2024/04/30 07:01


单例模式其实从名字上就可以看出来,在整个程序运行的过程中,只能且仅有一个实例存在。

后来随着各位大神们再一次的细化,又分出来当初的经典模式,以及以加载时间来区分的饿汉模式和延迟加载模式

我们先来看一下刚开始我们的写法(其实这个也是延迟加载的写法了):


public class SingleObject    {        private SingleObject() { } //私有构造        private static SingleObject instance;//实例对象        private static object lockObj = new object();  //锁        public static SingleObject CreateInstance()  //获取单例对象的方法        {            if (instance == null)  //如果实例不存在需要创建实例            {                lock (lockObj)                {                   
                    if (instance == null) //为什么还要判断,因为有可能在你lock的时候这个实例已经被别人创建了,所以,在lock的时候再判断一下实例是否为null,这个还是有必要的
  instance = new SingleObject(); } } return instance; } }

其实一个单例模式只要记住三点就可以了,上面的代码为什么要用lock呢?我们知道,现在很多系统都是存在并发的,可能一个对象同时有不止一个线程在使用,如果不加lock,有可能实例会被创建大于一次,那么这个单例模式就可能变成多例模式了,C#中没有系统提供的线程同步方法,这一点貌似java比较简单,呵呵。

一是构造函数必须私有,为什么呢,如果你存在公有的构造函数,那大家不是可以随便new一个instance出来了么,还怎么叫做单例呢?

二是要创建的instance必须是全局唯一的,也就是说必须是一个静态的,为什么呢?因为静态的变量是跟程序的生命周期一致的,在应用程序创建的时候创建,随着应用程序的结束而结束,如果不是静态的,有可能在某次GC的时候就被回收了。

三是要提供一个全局的静态方法得到实例,一般来讲,单例模式都是有实例自身向外界提供一个静态的公共方法来提供自己的实例。

下面我们看看立即加载模式(又称饿汉方式)

public class SingleObject    {        private SingleObject() { } //私有构造        private static SingleObject instance=new SingleObject();//实例对象        public static SingleObject CreateInstance()  //获取单例对象的方法        {            return instance;        }    }

从代码的结构来看,这种方法少了一个全局的object锁对象,实例还是静态的,不过唯一与延迟加载的区别在于这个实例在创建的时候就已经new好了,我们都知道,静态变量在程序启动之初就会被创建,我们也不必要担心说同时会创建多个实例出来,这些问题CLR会帮你搞定的,所以它的获取实例的方法就不用去判断instance是不是null了,直接返回就可以了。


写了这么多,单例模式用在哪些场景呢?

比如我们的windows系统的任务管理器,这个好像还没有人能同时打开第二个的。

当然了,在我们实际的系统中肯定也有用到,我常用到的地方有:

有一个任务队列,用多线程处理,每个线程每次都从队列中领取一个任务,处理完后再领取下一个任务。为了保证每个任务只能被线程中的一个线程领取,这个任务分配/领取的地方就需要单例模式来控制并发现象的产生。

比如说现在流行的网上商城,如果用程序创建订单号的话,那肯定也是单例模式,你不能一个订单号对应2个订单的吧,当然了,很多时候创建订单号是由数据库完成的,我们现在的做法就是用数据库控制的。

单例模式现在是设计模式中用的比较多的一个模式,在我们日常设计的很多系统中都会存在。

	
				
		
原创粉丝点击