代码改变世界

设计模式_1_单例模式

2012-05-16 01:28  Mike.Jiang  阅读(505)  评论(2编辑  收藏  举报

    单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。  

    应用场景:当系统中需要一个类仅有一个实例时,才需要用到单例(有人会说,那我只实例化一次不就好了吗,如果确定只用一次,并且也不需要考虑扩展,那也是可以的)。但事实上,在很多应用中,会在多个地方用到这个实例,正常的一种解决方案是:在一个公共类中,声明一个静态只读的类空的实例,然后再定义一个静态的方法获取这个实例,在这个方法中判断是否已经存在某个实例。

    但是我认为一个类可以被实例化的次数的控制是这个类本身自己的责任,并且当业务需要可以实例化有限个实例,也将改动那个公共类。所以大师们根据以往的经验,提出了这样的一个单例的设计模式。理解单例模式主要要理解它的应用场景以及类的职能划分。

   下面给了两种单例的实现


   单线程的单例

  

View Code
    /// <summary>
    /// 单线程的单例模式
    /// </summary>
    public class Singleton
    {
        private static Singleton instance;

        private Singleton()//阻止类的默认实例化方法
        {
 
        }

        /// <summary>
        /// 定义一个获取实例的全局唯一的方法
        /// </summary>
        /// <returns></returns>
        public static Singleton GetInstance() 
        {
            //如果实例不存在,则实例化一个新的实例,否则返回已有的实例
            if (instance == null) 
            {
                instance = new Singleton();
            }
            return instance;
        }
    }

   多线程单例

  

View Code
public class Singleton2
    {
        private static Singleton2 instance;

        private static readonly object syncRoot = new object();//用于在运行时创建一个静态只读的进程辅助对象
        private Singleton2() 
        {

        }

        public static Singleton2 GetInstance()
        {
            if (instance == null) //如果对象已经存在,刚直接返回实例,否则才进行加锁操作
            {
                //mark1
                lock (syncRoot) 
                {
                    /*
                    可能有两个以上的进程进入mark1的位置,第一个进程加锁,创建实例然后释放锁;
                    接着第二个进程加锁进来,如果没有此句的第二次判断实例是否为空,则可能会产生多个实例
                    */
                    if (instance == null) 
                    {
                        instance = new Singleton2();
                    }
                }
            }
            return instance;
        }
    }