C#设计模式一 (单例模式singleton)

C#单例设计模式

一、引言

单例设计模式属于创建型模式。

什么情况下用到单一设计模式呢?

1、在软件中,经常有一些特殊的类,必须保证它仅仅实例唯一一个对象。才能保证它们的逻辑正确性及良好的效率。

2、当然出于上面的一个目的,我们要限制用户使用new关键字,否则无法控制“唯一对象”的要求。我们更不能要求用户去遵守单一原则,而是从我们设计者本本身来限制。即这应该是类设计者的责任,而不是使用者的责任。

单一实例模式的目的:

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

二、单一实例模式实现步骤

简单来说,实现步骤也就是三步:

1、在类中存有一个静态的类的对象。
2、将构造函数私有化,限制用户在类体外使用new。杜绝实例重复
3、开放一个公开访问的全局访问点。

三、实现单例模式的几种方法:

    /*方法1:
     * 此方法在单线程中完全没问题
     * 在多线程中可能会有问题,例如两个线程同时访问,并同时执行到判断instance==null语句
     * 那么两个线程返回的结果都是true的话,则instance=new Singleton2;语句就会执行2次,
     * 当然这种概率特别低,但也不能排除此可能性。  
     * 
     * 此外这种方式比较省资源,因为如果不访问GetInstance属性的情况下,instance永远为空。
     */
    class Singleton1
    {
        private static Singleton1 instance;//只声明一个静态对象但没赋值,所以不会死循环
        private static readonly object syncRoot = new object();
        private Singleton1()//私有构造函数,外部无法调用,所以无法使用new关键字创建对象
        {
        }

        public static Singleton1 GetInstance()//静态方法,无需新建对象即可使用,解决无法使用new的问题
        {
            if (instance == null)   //如果静态对象instance没有引用任何内存,说明本次是第一次使用
            {

                lock (syncRoot)
                {

                    if (instance == null)//没有实例,则直接new一个。
                    {
                        instance = new Singleton1();
                    }
                }
            }
            return instance;    //否则说明类已经实例化了,所以不能再实例,直接返回已有的对象
        }

    }


    /*方法2:
     * 此方法在单线程中完全没问题
     * 在多线程中可能会有问题,例如两个线程同时访问,并同时执行到判断instance==null语句
     * 那么两个线程返回的结果都是true的话,则instance=new Singleton2;语句就会执行2次,
     * 当然这种概率特别低,但也不能排除此可能性。 
     * 
     * 此外这种方式比较省资源,因为如果不访问Instance属性的情况下,instance永远为空。
     */
    public sealed class Singleton2  
    {
        private static Singleton2 instance = null;
        private Singleton2() { }
        public static Singleton2 Instance //无论在哪里,用到Singleton.Instance,其值都一样。
        {
            get 
            {
                if (instance == null)  //此处判断instance是否已被赋值,确保只能new一次
                    instance= new Singleton2();
                
                return instance;
            }
        }

    }

    /*方法3:
     * 此方法在单线程和多线程中都没问题。因为静态变量在编译后就会生成唯一的instance,使用
     * 不会再生成,所以它们访问的永远是同一个instance。
     * 
     * 此外这种方式比较浪费资源。无论你用不用GetInstance方法,instance都早已有值。 
     */
    public sealed class Singleton3
    {
        private static readonly Singleton3 instance = new Singleton3();  //直接静态new一个,后期不会重复
        private Singleton3() { }  //私有构造函数,避免用户使用new
        public static Singleton3 GetInstance()  //开放一个全局访问点,返回当前的instance,且为唯一
        {
            return instance;
        }
    }
发布了50 篇原创文章 · 获赞 0 · 访问量 850

猜你喜欢

转载自blog.csdn.net/weixin_40786497/article/details/104197959