I am here to continue the learning series regarding Design Patterns. Today we will go through one of the popular design pattern called Singleton.
In case you have not had a look at our first article, go through the following link:
Before talking about its implementation let’s begin with some fundamental questions as in the following.
Use of the Singleton Pattern
As the name suggests, the Singleton Pattern allows only one instance of a class to be created.
Let's start by putting some questions to understand the concept.
When do we need to have only one instance of a class?
There are many possible requirements for a instance of a class but they all tend to have the one objective that we don’t want to change the state of the object or we want to keep the class stateless.
A simple example could be that you want to load some master data at once and let the consumers of the data make a call to the Singleton class instead of each consumer making various calls by creating a new instance.
In general, in any complex enterprise application, Repository and Data Access Layer classes can be seen as a Singleton since typically we don’t want them to maintain the state in these layers.
Some other example could be cross-cutting concerns like Logging, Configuration, Caching and so forth that can also be implemented as a Singleton since we want a single and global point of access to these classes.
Apart from the core consideration explained above, I have seen that developers, mostly not so experienced sometimes, create unnecessarily instances that creates not just an overhead to memory but also impacts the overall performance of an application.
Why not Static classes?
There can be several reasons why to not use a static class however I can think of a few as follows.
- There can be cases where you want to implement interfaces (maybe to implement IOC, I will explain IOC later) in a class that can be done in a Singleton implementation but not in the static one.
- If required, you can use a singleton class as a method parameter whereas you cannot do that with a static class.
Special care for Singleton classes
We need to take special care for Singleton classes. The idea of a state of a class comes with some extra care that means we need to handle synchronization issues in multi-threaded environments.
Enough theory, now let’s talk about implementation.
Let’s have a look at the most basic implementation.
In the first example below, we have implemented a Singleton with Lazy loading since the instance will not be created until the caller calls the GetInstance method for the first time.
- public class SingletonClass
- {
- private static SingletonClass instance = null;
- private SingletonClass() {}
- public static SingletonClass GetInstance
- {
- get
- {
- if (instance == null)
- {
- instance = new SingletonClass();
- }
- return instance;
- }
- }
- }
Let’s try to fix the sync issue that may arise in multi-threaded environments. For this, we will use a double-lock mechanism.
- public class SingletonClass
- {
- private static SingletonClass instance = null;
- private static object lockMe = new object();
- private SingletonClass() {}
- public static SingletonClass GetInstance
- {
- get
- {
- if (instance == null)
- {
- lock(lockMe)
- {
- if (instance == null)
- {
- instance = new SingletonClass();
- }
- }
- }
- return instance;
- }
- }
- }
And in the last, Singleton with static initializations. Please note that the .NET Framework guarantees thread safety for static initialization so we don’t need extra care for sync issues however we may not get the benefit of lazy loading of objects here.
- public class SingletonClass
- {
- private static SingletonClass instance = new SingletonClass();
- private SingletonClass() {}
- public static SingletonClass GetInstance
- {
- get
- {
- return instance;
- }
- }
- }
Conclusion:
In the article, we have gone through what singleton design pattern is, when it should be used and how it should be used. You can also download the attached demo project (SingletonPatternDemo.zip) to go through the source code referred in the article
I hope you will find this article useful. Look forward to your comments/suggestions.