单件模式的使用意图就是:保证一个类仅有一个实例,并提供一个该实例全局的访问点(这句话当然不是我先说的,是引用Gof在《设计模式》中的一句话)
单件模式本质就是控制对象的构建,如果你把对象构建的方法给了类的使用者,你就无法控制类对象的构建个数,要控制类对象的构建个数,就要自己掌握类的构建方法,类的构建方法不被其他类使用者使用,所以,类的构建方法私有化可以达到限制的目的。
单件模式的实现:
在单线程的情况下:私有化构造函数,使类的使用者调用不到这个构造函数来new一个实例。类型中可以自己new一个实例。类中创建一个静态私有变量和Static公有属性。在公有属性中实现此类的实例化。这样在第一次请求时创建此对象。代码如下:
class Singleton
{
private static Singleton _instance;
private Singleton(){}
public static Singleton f_Instance
{
get
{
if(_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
这种单线程下的单件模式有几点要注意:
1、 构造器私有化(如果要此类被继承,可以用protected声明构造器)
2、 不要支持IClinieable接口,因为会导致多个对象实例的出现
3、 不能支持序列化
4、 单件模式只考虑了对象创建的管理,没有考虑对象的销毁管理(创建自己的对象,销毁的事交给垃圾回收器吧)
5、 不能应对多线程环境,因为会导致多个对象实例的出现
那在多线程下如何实现呢?代码如下:
class SingletonMuli//多线程Singleton模式
{
private static volatile SingletonMuli _instance;
//volatile是为了让编译器对此代码编译后的位置不进行调整
private SingletonMuli(){}
private static object lockHelper = new object(); //辅助器,不参与对象构建
public static SingletonMuli f_Instance
{
get
{
if(_instance == null)
{
lock(lockHelper)
{
if(_instance == null) //双检查
{
_instance = new SingletonMuli();
}
}
}
return _instance;
}
}
}
当然还有一些更简单的实现方法,如:
class Singleton1//可以用在多线程环境
{
public static readonly Singleton1 _instance = new Singleton1();
private Singleton1(){}
}
其中要提到的是在_instance私有字段的实例化叫做“内联初始化”。内联初始化是指在声明时。
实际上面的代码上相当于如下代码:
Public static readonly Singleton1 _instance;
Static Singleton() //静态构造函数
{
_instance = new Singleton(); //私有构造器
}
Private Singleton(){}
内联初始化时会先执行静态构造器,如果没有静态构造函数,系统会默认一个。在访问此静态字段时执行静态构造器生成。静态构造器保证了在多线程时只有一个线程执行,自动加锁。