一,模式分类
目的
范围
二,Singleton模式
1,动机Motivation
在软件系统中 有一些特殊类,必须保证他们在系统中只有一个存在(只有一个实例)才能保证他们的逻辑正确性,以及良好的效率。
这种动机是类的设计者的责任(由设计类的人保证),而不是使用者的责任。
如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例。
2,意图
保证一类只有一个实例,并提供一全局访问点
三,Singleton模式的要点
1,Singleton模式中的实例构造器可以设置为protected以允许子类派生
2,Singleton模式不需要支持Icloneable接口(该接口用于克隆),会导致多个对象实例
3,一般不要支持序列化,同上(序列化的方式也可以创建对象)
4,只考虑了对象创建管理,没有考虑对象销毁的管理。因为开销较小(仅有一个),所以没有必要对其销毁进行特殊的管理。
5,不能应用多线程环境,在多线程环境中,使用Singleton模式任然有可能得到多个实例对象。
四,Singleton模式的扩展
1,将一个实例扩展到n个实例,例如对象池的实现
n并不是任意,而是可控制的范围,
如,建立一个服务队列,在初始化的过程中用new构造出n个对象,再轮询调用
2,将new构造器的调用转移到其他类中,例如多个类协同工作环境中,某个局部环境只需要拥有一个类的一个实例
3,理解和扩展Singleton模式的核心是:“如何控制用户使用new对一个类的实例构造器的任意调用”
即使很好的控制new,new太自由
五,实例
1,单线程Singleton模式
2,多线程Singleton模式
3,更好的Singleton模式的实现(多线程对应)
//更好的Singleton模式的实现(多线程对应)
//密封类不可以继承
sealed class Singleton3
{
/*
* ① 实现了内联初始化,实际上编译后静态字段会被加入静态构造器中执行(实现初始化)
* 而我们在使用静态变量之前,类的静态构造器会被首先执行
* 所以我们只要方法该字段就能保证它们初始化
* ② 支持多线程,
* .net机制本身就保证只有一个线程能执行静态构造器,可以免费为静态构造器加锁
* ③ 弊端
* 该方式不能支持带参数的构造器
* 根本原因在于静态构造器是私有的,不带参数的,
* 在一定程度上,可以定义一些属性来解决这一问题(如果仅仅是简单的设置值的话),或者
* 定义个单独的初始化方法来实现初始化,如,加入public void Init() { ...}方法实现初始化
* ④ 而且由于类一加载就实例化对象,所以要提前占用系统资源(前面都是用时才实例化)
*/
public static readonly Singleton3 Instance = new Singleton3();
private Singleton3() { }
}
//上类等同于此类
class Singleton4
{
public static readonly Singleton4 Instance;
//静态的构造器,执行时间
static Singleton4()
{
Instance = new Singleton4();
}
private Singleton4() { }
}
4,其他实例
//一,.net环境中GetType方法返回的对象,就是用了该模式
int[] array1 = new int[] { 1, 2, 3 };
int[] array2 = new int[] { 4, 5, 6 };
Type t1 = array1.GetType();
Type t2 = array2.GetType();
//ReferenceEquals判断t1,t2是否指向同一地址
Console.WriteLine(ReferenceEquals(t1, t2));
//结果为true
//二,在配置类中访问的HttpContext都是全局唯一的对象
//HttpContext.Current
}