c# design pattern-creative pattern singleton pattern

Table of contents

Foreword:

advantage:

shortcoming:

Hungry Chinese style (static variable mode)

Lazy style (thread unsafe)

Lazy Man Style (Double Check Lock)

Recommended methodLazy

Summarize:


Foreword:

This pattern involves a single class that is responsible for creating its own objects while ensuring that only a single object is created. This class provides a way to access its unique objects directly, without the need to instantiate an object of the class.

There are two types of singleton design patterns:

  1. Hungry Chinese style: Class loading will cause the single instance object to be created
  2. Lazy style: Class loading does not cause the single-instance object to be created, but is created when the object is used for the first time.

advantage:

  1. This ensures that there is only one instance in the memory, reducing memory overhead;
  2. Avoid multiple occupation of resources;
  3. Set global access points to optimize and share access to resources.

shortcoming:

  1. Generally there is no interface and expansion is difficult;
  2. During the debugging process, if the code in the singleton has not been executed, a new object cannot be simulated;
  3. If the functional code design is unreasonable, it is easy to violate the single responsibility principle.

Hungry Chinese style (static variable mode)

public class Singleton
{
    //私有构造方法
    private Singleton()
    {
    }

    //在成员位置创建该类的对象
    private static Singleton _sSingleton = new Singleton();
    
    //对外提供静态方法获取该对象
    public static Singleton GetSingleton()
    {
        return _sSingleton;
    }
}

This method creates a Singleton type static variable and creates a static object _sSingleton. In this method, the _sSingleton object is created as the class is loaded. Because it is modified by the static modifier, if the object is not used, it will cause a waste of memory. .

Lazy style (thread unsafe)

public class Singleton
{
    //私有构造方法
    private Singleton()
    {
    }

    //在成员位置创建该类的对象
    private static Singleton? _sSingleton;


    //对外提供静态方法获取该对象
    public static Singleton GetSingleton()
    {
        if (_sSingleton == null)
        {
            _sSingleton = new Singleton();
        }

        return _sSingleton;
    }
}

After declaring a Singleton type static variable in this way, the object is not assigned immediately. Instead, when GetSingleton is called, _sSingleton is judged whether it is the first call, and if so, the value is assigned, thus achieving the lazy loading effect. But if it is a multi-threaded environment, thread safety issues will arise.

Lazy Man Style (Double Check Lock)

To solve thread safety issues we can use the lock keyword

The lock keyword is used in C# to create a critical section, which ensures that only one thread can execute the code block restricted by it at the same time. How to use it:

lock (variable) {
   // 被保护的代码块。
}

As follows, use  lock the statement to ensure that only one thread can enter the code segment at a time, thereby preventing multiple Singleton instances from being created in a multi-threaded environment. If other threads attempt to enter the locked code, then they will block (i.e., suspend execution) until the original thread exits the locked code. Therefore, it is easy to cause thread blocking

public class Singleton
{
    //定义了一个静态只读的对象_lockObject,用于控制对实例对象的访问
    private static readonly object _lockObject = new object();
    private static Singleton? _sSingleton;

    private Singleton()
    {
    }


    public static Singleton Instance
    {
        get
        {
            lock (_lockObject)
            {
                if (_sSingleton == null)
                {
                    _sSingleton = new Singleton();
                }

                return _sSingleton;
            }
        }
    }
}

Recommended methodLazy

Using Lazy<> is a recommended way to implement a thread-safe singleton pattern in C#, which has been available since .NET 4.0. Because the Lazy<> type is thread-safe and provides good support for lazy initialization. Lazy takes care of all thread safety issues and is currently the preferred way to create singletons in C#.

public sealed class Singleton
{
   private static readonly Lazy<Singleton> lazy =
      new Lazy<Singleton>(() => new Singleton());

   public static Singleton Instance { get { return lazy.Value; } }
   private Singleton()
   {
   }
}

Summarize:

The singleton mode can only produce one object to the outside world. The hungry mode creates this object in advance, while the lazy mode creates it when it is used. Comparison: From a memory perspective, the lazy mode only creates it when it is used, which saves more memory; from a speed perspective , Hungry Han has been created in advance, and it will be faster to obtain the object.

 

Guess you like

Origin blog.csdn.net/weixin_65243968/article/details/132154462