设计模式(一)——单例模式

单例模式是设计模式中最简单的一种,主要目的就是确保程序运行期间只有一个对象被创建。

特点:构造函数私【私有】、类内部有【私有】自身类型的属性、提供获取实例的静【静态】方法;

好处是大大减少了对象创建时的性能损耗和内存占用;

单例模式的创建方式有 懒汉模式、饿汉模式、双重锁模式、静态内部类单例模式、枚举单例模式

1、懒汉模式:

/// <summary>
        /// 懒汉单例
        /// </summary>
        public class SingletonLH {
            /// <summary>
            /// 私有的自身类型的属性
            /// </summary>
            private static SingletonLH singletonLH;
            /// <summary>
            /// 私有构造函数
            /// </summary>
            private SingletonLH(){}
            /// <summary>
            /// 获取对象的静态方法
            /// </summary>
            /// <returns></returns>
            public static SingletonLH GetSingletonLH() {
                if (singletonLH is null)
                    singletonLH = new SingletonLH();
                return singletonLH;
            }
        }

缺点:线程不安全、延迟初始化,严格意义上不算是单例模式,基本上不会有人用

2、饿汉模式

 /// <summary>
        /// 饿汉单例
        /// </summary>
        public class SingletonEH
        {
            /// <summary>
            /// 私有的自身类型的属性
            /// </summary>
            private static SingletonEH singletonEH = new SingletonEH();
            /// <summary>
            /// 私有构造函数
            /// </summary>
            private SingletonEH(){}
            /// <summary>
            /// 获取对象的静态方法
            /// </summary>
            /// <returns></returns>
            public static SingletonEH GetSingletonLH()
            {
                return singletonEH;
            }
        }

好处:线程安全,只初始化一次、内存中仅留存一份,不会被拷贝

坏处:程序开始的时候就初始化,如果一直不用会存在内存浪费,占用资源

3、双重锁模式

/// <summary>
        /// 双重锁单例模式
        /// </summary>
        public class SingletonSCS
        {
            /// <summary>
            /// 私有的自身类型的属性
            /// </summary>
            private volatile static SingletonSCS singletonSCS;
            /// <summary>
            ////// </summary>
            private static readonly object _lockSCS = new object();
            /// <summary>
            /// 私有构造函数
            /// </summary>
            private SingletonSCS() { }
            /// <summary>
            /// 获取对象的静态方法
            /// </summary>
            /// <returns></returns>
            public static SingletonSCS GetSingletonLH()
            {
                //第一次判断
                if (singletonSCS is null)
                {
                    //加锁
                    lock(_lockSCS) {
                        //第二次判断
                        if (singletonSCS is null)
                            singletonSCS = new SingletonSCS();
                    }
                }
                return singletonSCS;
            }
        }

好处:线程安全,延迟初始化,使用Volatile声明的变量就相当于告诉编译器,我不要把这个变量写Cache,因为这个变量是可能发生改变的。

4、静态内部类单例模式

/// <summary>
        /// 静态内部类单例模式
        /// </summary>
        public class SingletonJTNBL
        {
            /// <summary>
            /// 私有构造函数
            /// </summary>
            private SingletonJTNBL() { }
            /// <summary>
            /// 获取对象的静态方法
            /// </summary>
            /// <returns></returns>
            public static SingletonJTNBL GetSingleton() {
                return innerClass.singletonJTNBL;
            }
            /// <summary>
            /// 一个静态内部类提供一个静态的实例
            /// </summary>
            private static class innerClass{
                public static SingletonJTNBL singletonJTNBL = new SingletonJTNBL();
            }
        }

好处:保证了对象的唯一性,是目前最为推荐的单例模式

5、枚举单例模式

c# 不支持这种写法,在c#中枚举是一个值类型,内部不存在方法一说

ps:针对大对象可使用Lazy<>进行延迟加载。

2019年10月22日23:20:03

往后三个星期,每天复习一个设计模式,Go

原文地址:https://www.cnblogs.com/yuchenghao/p/11723367.html