C#单例设计模式
一、引言
单例设计模式属于创建型模式。
什么情况下用到单一设计模式呢?
1、在软件中,经常有一些特殊的类,必须保证它仅仅实例唯一一个对象。才能保证它们的逻辑正确性及良好的效率。
2、当然出于上面的一个目的,我们要限制用户使用new关键字,否则无法控制“唯一对象”的要求。我们更不能要求用户去遵守单一原则,而是从我们设计者本本身来限制。即这应该是类设计者的责任,而不是使用者的责任。
单一实例模式的目的:
保证一个类仅有一个实例,并提供一个该实例的全局访问点。
二、单一实例模式实现步骤
简单来说,实现步骤也就是三步:
1、在类中存有一个静态的类的对象。
2、将构造函数私有化,限制用户在类体外使用new。杜绝实例重复
3、开放一个公开访问的全局访问点。
三、实现单例模式的几种方法:
/*方法1:
* 此方法在单线程中完全没问题
* 在多线程中可能会有问题,例如两个线程同时访问,并同时执行到判断instance==null语句
* 那么两个线程返回的结果都是true的话,则instance=new Singleton2;语句就会执行2次,
* 当然这种概率特别低,但也不能排除此可能性。
*
* 此外这种方式比较省资源,因为如果不访问GetInstance属性的情况下,instance永远为空。
*/
class Singleton1
{
private static Singleton1 instance;//只声明一个静态对象但没赋值,所以不会死循环
private static readonly object syncRoot = new object();
private Singleton1()//私有构造函数,外部无法调用,所以无法使用new关键字创建对象
{
}
public static Singleton1 GetInstance()//静态方法,无需新建对象即可使用,解决无法使用new的问题
{
if (instance == null) //如果静态对象instance没有引用任何内存,说明本次是第一次使用
{
lock (syncRoot)
{
if (instance == null)//没有实例,则直接new一个。
{
instance = new Singleton1();
}
}
}
return instance; //否则说明类已经实例化了,所以不能再实例,直接返回已有的对象
}
}
/*方法2:
* 此方法在单线程中完全没问题
* 在多线程中可能会有问题,例如两个线程同时访问,并同时执行到判断instance==null语句
* 那么两个线程返回的结果都是true的话,则instance=new Singleton2;语句就会执行2次,
* 当然这种概率特别低,但也不能排除此可能性。
*
* 此外这种方式比较省资源,因为如果不访问Instance属性的情况下,instance永远为空。
*/
public sealed class Singleton2
{
private static Singleton2 instance = null;
private Singleton2() { }
public static Singleton2 Instance //无论在哪里,用到Singleton.Instance,其值都一样。
{
get
{
if (instance == null) //此处判断instance是否已被赋值,确保只能new一次
instance= new Singleton2();
return instance;
}
}
}
/*方法3:
* 此方法在单线程和多线程中都没问题。因为静态变量在编译后就会生成唯一的instance,使用
* 不会再生成,所以它们访问的永远是同一个instance。
*
* 此外这种方式比较浪费资源。无论你用不用GetInstance方法,instance都早已有值。
*/
public sealed class Singleton3
{
private static readonly Singleton3 instance = new Singleton3(); //直接静态new一个,后期不会重复
private Singleton3() { } //私有构造函数,避免用户使用new
public static Singleton3 GetInstance() //开放一个全局访问点,返回当前的instance,且为唯一
{
return instance;
}
}