单例模式
单例模式:通过单例模式的方法创建的类在当前进程中只有一个实例
要求:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
属于
创建型(Creational)模式:负责对象创建,我们使用这个模式,就是为了创建我们需要的对象实例的。
其他:
结构型(Structural)模式:处理类与对象间的组合
行为型(Behavioral)模式:类与对象交互中的职责分
单例模式 实际场景:
/// <summary>
/// 定义一个天气类
/// </summary>
public class WeatherForecast
{
public WeatherForecast()
{
Date = DateTime.Now;
}
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string Summary { get; set; }
}
[HttpGet]
public WeatherForecast Get()
{
// 实例化一个对象实例
WeatherForecast weather = new WeatherForecast();
return weather;
}
演变一:定义一个静态变量来保存类的唯一实例
定义私有构造函数,使外界不能创建该类实例
/// <summary>
/// 定义一个天气类
/// </summary>
public class WeatherForecast
{
// 定义一个静态变量来保存类的唯一实例
private static WeatherForecast uniqueInstance;
// 定义私有构造函数,使外界不能创建该类实例
private WeatherForecast()
{
Date = DateTime.Now;
}
/// <summary>
/// 静态方法,来返回唯一实例
/// 如果存在,则返回
/// </summary>
/// <returns></returns>
public static WeatherForecast GetInstance()
{
// 如果类的实例不存在则创建,否则直接返回
// 其实严格意义上来说,这个不属于【单例】
if (uniqueInstance == null)
{
uniqueInstance = new WeatherForecast();
}
return uniqueInstance;
}
public DateTime Date { get; set; }public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string Summary { get; set; }
}
缺点:多线程情况下会走两边构造函数,即生成多个类 ,要解决多线程情况下唯一就要加锁
// 定义一个锁,防止多线程
private static readonly object locker = new object();
public static WeatherForecast GetInstance()
{
// 当第一个线程执行的时候,会对locker对象 "加锁",
// 当其他线程执行的时候,会等待 locker 执行完解锁
lock (locker)
{
// 如果类的实例不存在则创建,否则直接返回
if (uniqueInstance == null)
{
uniqueInstance = new WeatherForecast();
}
}
return uniqueInstance;
}
这样就还有一点点问题:创建对象了之后就只用管对象是不是为空 不用判断是否加锁了 因为有了对象就不用再创建了
public static WeatherForecast GetInstance()
{
// 当第一个线程执行的时候,会对locker对象 "加锁",
// 当其他线程执行的时候,会等待 locker 执行完解锁
if (uniqueInstance == null)
{
lock (locker)
{
// 如果类的实例不存在则创建,否则直接返回
if (uniqueInstance == null)
{
uniqueInstance = new WeatherForecast();
}
}
}
return uniqueInstance;
}
那么singleton是不是单例呢
/ 单例注册到容器内 services.AddSingleton<Feeling>(); 结论:Singleton是一种单例,而且还是双检锁那种, 因为结论可以看出,我们使用单例模式,直接可以使用依赖注入 Sigleton 就能满足的,很方便
原文:https://www.cnblogs.com/laozhang-is-phi/p/Singleton-Pattern.html
浙公网安备 33010602011771号