保证一个类仅有一个实例,并提供一个该实例的全局访问点。 -《设计模式》 GoF
a.单线程Singleton模式的几个要点
- 实例构造器可以设置为protected以允许子类派生。
- 一般不要持之ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。
- 一般不要支持序列化,因为这也有可能导致多个对象实例,与Singleton模式的初衷违背。
- 只考虑到了对象创建的管理,没有考虑对象的销毁管理。就支持垃圾回收的平台和对象的开销来讲,一般没必要对其销毁进行特殊管理。
- 不能应对多线程环境:在多线程环境下,使用Singleton模式仍然有可能得到多个实例对象。
b.单线程Singleton举例
/// <summary>
/// 单例模式
/// </summary>
class Singleton
{
/// <summary>
/// 单例对象
/// </summary>
private static Singleton instance;
/// <summary>
/// 私有构造函数
/// </summary>
private Singleton()
{ }
/// <summary>
/// 单例对象属性
/// </summary>
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
c.多线程Singleton举例
class MultithreadingSingleton
{
// 关于volatile:https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/volatile
private static volatile MultithreadingSingleton instance = null;
/// <summary>
/// lock帮助对象
/// </summary>
private static object lockHelper = new object();
/// <summary>
/// 构造函数
/// </summary>
private MultithreadingSingleton()
{ }
/// <summary>
/// 单例属性
/// </summary>
public static MultithreadingSingleton Instance
{
get
{
// 双检查instance
if (instance == null)
{
lock (lockHelper)
{
if (instance == null)
{
instance = new MultithreadingSingleton();
}
}
}
return instance;
}
}
}
d.static Singleton代码举例
/// <summary>
/// 静态单例模式
/// </summary>
class StaticSingleton
{
/// <summary>
/// 静态只读单例对象
/// </summary>
public static readonly StaticSingleton Instance = new StaticSingleton();
/// <summary>
/// 构造函数
/// </summary>
private StaticSingleton()
{ }
}
/// <summary>
/// 静态单例模式
/// </summary>
class StaticSingletonSpread
{
/// <summary>
/// 静态只读单例对象
/// </summary>
public static readonly StaticSingletonSpread Instance;
/// <summary>
/// 静态构造函数
/// </summary>
static StaticSingletonSpread()
{
Instance = new StaticSingletonSpread();
}
/// <summary>
/// 私有构造函数
/// </summary>
private StaticSingletonSpread()
{
}
}
e.Singleton模式扩展
- 将实例扩展到n个实例,例如对象池的实现。
- 将new构造器的调用转移到其他类中,例如多个类协同工作环境中,某个局部变量只需要拥有某个类的一个实例。
- 理解和扩展Singleton模式的核心是“如何控制用户使用new对一个类的实例构造器的任意调用”。