【设计模式】面向对象设计七大原则
【设计模式】设计模式概念和分类
【设计模式】C#设计模式:单例模式
【设计模式】C#设计模式:工厂方法模式
【设计模式】C#设计模式:抽象工厂模式
【设计模式】C#设计模式:建造者模式
【设计模式】C#设计模式:原型模式
定义
单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。
单例模式的要点有三个:
(1)单例类只有一个实例;
(2)该单例实例必须由单例类自行创建;
(3)单例类对外提供一个访问该实例的全局访问点;
单例模式是一种对象创建型模式。单例模式又名单件模式或单态模式。
单例模式的结构
单例模式的目的是保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式包含的角色只有一个,就是单例类——Singleton。单例类拥有一个私有构造函数,确保用户无法通过new关键字直接实例化它。除此之外,该模式中包含一个静态私有成员变量与静态公有的工厂方法,该工厂方法负责检验实例的存在性并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建。
在单例模式的实现过程中,需要注意如下三点:
(1)单例类的构造函数为私有;
(2)提供一个自身的静态私有成员变量;
(3)提供一个公有的静态工厂方法。
单例模式的实现
单例模式有懒汉式和饿汉式两种实现形式。
懒汉式(线程不安全)
该模式的特点是类加载时没有生成单例,只有当第一次调用 GetInstance 方法才去创建单例。
/// <summary>
/// Singleton class. Thread unsafe.
/// </summary>
public class Singleton
{
private Singleton() { }
private static Singleton _Instance = null;
/// <summary>
/// Get an instance of the Singleton class.
/// </summary>
public static Singleton GetInstance()
{
if (_Instance == null)
{
_Instance = new Singleton();
}
return _Instance;
}
}
将存在线程非安全的问题。在多线程、高并发的情况下,可能同时产生多个实例,违背了单例模式。
饿汉式(线程安全)
该模式的特点是类一旦加载就创建一个单例,保证在调用 GetInstance 方法之前单例已经存在了。
/// <summary>
/// Singleton class. Thread safety.
/// </summary>
public class Singleton
{
private Singleton() { }
// Instantiate yourself when you are loaded
private readonly static Singleton _Instance = new Singleton();
/// <summary>
/// Get an instance of the Singleton class.
/// </summary>
public static Singleton GetInstance()
{
return _Instance;
}
}
饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,以后线程安全的,可以直接用于多线程而不会出现问题。
懒汉式双重锁模式(线程安全)
保证多线程中只存在唯一实例
/// <summary>
/// Singleton class. Thread safety.
/// </summary>
public class Singleton
{
private Singleton() { }
private static Singleton _Instance = null;
private static readonly object sysLock = new object();
/// <summary>
/// Get an instance of the Singleton class
/// </summary>
public static Singleton GetInstance()
{
lock (sysLock)
{
if (_Instance == null)
{
_Instance = new Singleton();
}
}
return _Instance;
}
}
lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。
泛型单例模式
对泛型类进行约束,T只能是一个Class,并且有一个公共无参构造函数
/// <summary>
/// Singleton base class. Thread safety.
/// </summary>
public abstract class Singleton<T> where T : class ,new()
{
private Singleton() { }
private static T _Instance = null;
private static readonly object sysLock = new object();
/// <summary>
/// Get an instance of the Singleton class
/// </summary>
public static T Instance
{
get
{
lock (sysLock)
{
if (_Instance == null)
{
_Instance = new T();
}
}
return _Instance;
}
}
}