英文: Singleton Pattern
单例模式确保的是对于整个系统而言,一个类的实例只会存在一个。单例模式通常分为懒汉和饿汉两种。
- 懒汉:类实例在第一次调用的时候才会去产生
- 饿汉:类实例早已存在,取的时候直接返回
1.1、懒汉方式
既然是单例模式,就是类实例是不能让外部直接new创建的,那么对于构造函数的私有化是必要的。 而且上面说过懒汉方式时在第一次调用的时候来创建类的实例,那么必须考虑并发,通常情况下对并发的控制是通过加锁来实现的:public class Singleton_Idler{private static volatile Singleton_Idler singleton_Idler = null;private static readonly object lock_obj = new object();// 构造函数私有化private Singleton_Idler() { }// 提供方法供外部调用产生实例,使用双判断加锁public Singleton_Idler CreateInstance() {if (singleton_Idler == null) {lock (lock_obj) {if (singleton_Idler == null) {singleton_Idler = new Singleton_Idler();}}}return singleton_Idler;}}
1.2、饿汉方式1
public class Singleton2 { // 直接先实例化 // 缺点就是在程序初始化后, 静态对象就被CLR构造了, 哪怕你没用 private static readonly Singleton2 instance = new Singleton2(); private Singleton2() { } public Singleton2 GetInstance => instance; }1.3、饿汉方式2
public class Singleton3 { private static Singleton3 instance = null; private Singleton3() { } // 通过静态构造函数实例化 // 静态构造函数在第一次使用该类之前被运行时调用,只会执行一次,外部不能访问 static Singleton3() { instance = new Singleton3(); } public Singleton3 GetInstance => instance; }1.4、总结
单例模式一般使用在要求一个类有且仅有一个对象的场景下, 比如EF的上下文对象,数据库的连接池对象等等。 如果项目中使用的依赖注入容器,比如Autofac,那么对于单例模式怎么实现我们是不必要如此关心的,直接使用提供的方法注入然后获取即可。
