单例模式是设计模式中最简单的一种,主要目的就是确保程序运行期间只有一个对象被创建。
特点:构造函数私【私有】、类内部有【私有】自身类型的属性、提供获取实例的静【静态】方法;
好处是大大减少了对象创建时的性能损耗和内存占用;
单例模式的创建方式有 懒汉模式、饿汉模式、双重锁模式、静态内部类单例模式、枚举单例模式
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