Singleton Design Parttern
The Singleton Design Pattern ensure a class has only one instance and provide a global point of access to it.
UML Class Diagram
The following are teh guidelines to implement the Singleton Design Pattern IN C#?
- We need to declare a constructor that should be private and parameterless. This is required because it will restrict the class to be inistantiated from outside teh class. It only inistantiates form within class.
- The class should be decalred as sealed which will ensure that it cannot be inherited. This is goinig to be useful when you are dealing with the nested class.
- We need to create a static private variable that is going to hold a reference to the singleton instance of the class.
- we also need to create a publice static propert/method which will return teh singleton instance of the class. This method or property fist checks if an instance of the singleton class is created or not. If the singleton instance is created, then it returns that singleton instance otherwise it will create an instance and then return that instance.
Real-Time Scenarios where we use the Singleton Design Pattern IN C#?
- Service Proxies: As we know invoking a Service API is an expensive operation in an application. The process that take most of time is creating the Service client in order to invoke the service API. if you create the service proxy as singleton then it will impove the performence of your application.
- Facads: You can create Databse connections as singleton which can improve the performance of the application.
- Data Sharing: If you have any constant values or configuration values then you can keep these values in Singleton so that these can read by other component of the application.
- Caching : As we know fetching data from a database is a time-consuming process. In your application, you can cache the master ans configuration in memory which will avoid the DB calls. In such situations, the SIngletone class can be used to handle the caching with thread synchronization in an efficient manner which drastically improve the performance of the application.
What are the Advantages of using the SIngleton Pattern IN C#?
- The first most important advantage of using the singleton design pattern in C# is that it takes care of concurrent access to the shared resource. That means if we are sharing a resource with multiple clients simulatneously, then conccurent access to that resource is well managed by the singleton design pattern.
- It can be lazy-loaded and also has Static initialization.
- To share common data i.e. mater data and configuration data which is not changed that frequently in an application. In that case, we need to cache the objects in memory.
- As it provides a single point of access to a particular instance, it is easy to maintain.
- To reduce the overhead of instantiating a heavy object again and again.
What are the Disadvantages of using the SIngleton Design Pattern in C#?
- Unit testing is very difficult because it introduces a global state into an application
- It reduces the potential for parallelism within a program because to access the singleton instance in a multi-threaded environment, you need to serialize the object by using locking.
why Singleton Design Pattern class declares the sealed class?
Whenever we defined a class wihin another class in C# then the inner class is called a nested class or child class. it will be compiled.
How to implement the thread-safe SIngleton Design Pattern?
- Tread-safe Singletone Implementation using Lock.
- Implementation Thread-Safe Singleton Design Pattern using Double-Check Locking.
- Using Eager Loading to implement Tread-Safe SIngleton Design Pattern
- Using lazy<T> Generic class to implement lazy loading in Singleton Design Pattern. The Lazy<T> generic is thread-safe.
what are the Similarties between Singleton and Static Class in C#?
- Both Static class and Singleton Class can have only one instance available in memory throughout the whole application.
- They both are used for holding the global state of an application which is going to be common for all clients.
- Both Static Classes and Singleton Classes can be implemented as Thread-Safe.
Memory Management of Static Class VS Singleton Class in C#?
There is a little confusion about the memory management of the Static and SIngleton Class in C#. The most important point that you need to remember is any class whether it is declared as static or any member of it is declared as static then that class or those static members would not be collected by Garbage Collector.
The Static Variables or Static Classes are not stored in the Stack memory. There is some specific space in Heap memory called High-Frequency Heap where the static classes and static variables are stored.This space is beyong the scope of Garbage Collector and hence, the memory gets released only when the corresponding Process or AppDomain gets unloaded.
As the singleton class holds a static referece, it cannot be collected by the Garbage Collector, and both (the Staic and Singleton Class) get destroyed only when the corresponding Process or AppDomain gets unloaded.
单例模式是最常见也是最简单的设计模式,保证一个类只有一个实例并且提供一个全局访问点,主要解决实例被频繁的创建和销毁可能带来内存消耗问题。
单例模式的特点:
1、私有无参构造函数
2、私有静态变量存储单个实例创建的引用
3、共有静态的全局访问点(可以是方式也可以是属性)
以下介绍多种实现方式:
1、线程不安全的单例
The multiple threads could have evaluated the test if (_intance==null) and fount it to be true, then multiple instances will be created, which violates the singleton parttern.
public sealed class SingletonPartternDemoV1 { private static SingletonPartternDemoV1? _instance; private SingletonPartternDemoV1() { } public static SingletonPartternDemoV1 Instance { get { if (_instance == null) _instance = new SingletonPartternDemoV1(); return _instance; } } }
2、线程安全单例
创建实例时加锁(lock),在同一个时刻只允许一个线程创建实例,带来的问题是效率,多个线程获取实例需要等待。
public sealed class SingletonPartternDemoV2 { private static readonly object _obj = new object(); private static SingletonPartternDemoV2? _instance; private SingletonPartternDemoV2() { } public static SingletonPartternDemoV2 Instance { get { lock (_obj) if (_instance == null) _instance = new SingletonPartternDemoV2(); return _instance; } } }
3、线程安全双重检测
可以检测多个线程获取实例等待的问题
public sealed class SingletonPartternDemoV3 { private static readonly object _obj = new object(); private static SingletonPartternDemoV3? _instance; private SingletonPartternDemoV3() { } public static SingletonPartternDemoV3 Instance { get { if (_instance == null) lock (_obj) if (_instance == null) _instance = new SingletonPartternDemoV3(); return _instance; } } }
4、线程安全没有锁
通过私有静态属性初始化实例
public sealed class SingletonDemoV4 { private static readonly SingletonDemoV4 instance = new SingletonDemoV4(); static SingletonDemoV4() { } private SingletonDemoV4() { } public static SingletonDemoV4 Instance { get { return instance; } } }
5、System.Lazy
/// <summary> /// 1 Using .Net4 or higher then you can use the System.Lazy<T> type to make the laziness really simple /// 2 You can pass a delegate to the constructor that calls the singleton constructor, which is done most easily with a lambda expression. /// 3 Allow you to check whether or not the instance has beed created with the IsValueCreated property. /// </summary> public sealed class SingletonDemoV5 { private SingletonDemoV5() { } private static readonly Lazy<SingletonDemoV5> instance = new Lazy<SingletonDemoV5>(() => new SingletonDemoV5(), true); public static SingletonDemoV5 Instance { get { return instance.IsValueCreated ? instance.Value : new SingletonDemoV5(); } } }