单例模式

单例模式:通过单例模式的方法创建的类在当前进程中只有一个实例

要求:  

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

 

posted on 2020-05-18 22:40  龍瀧尨呀  阅读(118)  评论(0编辑  收藏  举报

导航