As we know design pattern is nothing but a way to pursue an intent that uses classes and their methods in an object oriented language.
When particular object in a system bears responsibility on which other objects rely, we need a way to find that responsible object. That particular responsible object will be the only one instance of that class. In this type scenarios we require Singleton design pattern that has only one instance with global access for it.
We have to follow some basic rules to implement the Singleton design pattern on any class.
There are two types of instantiation in Singleton design pattern. Those are Lazy instantiation and Eager instantiation.
Lazy instantiation:
In Lazy instantiation, instance of the singleton class not going to create until it is first used. Lazy initializing is useful when we don’t have enough information to instantiate the singleton class or we can select Lazy instantiation when singleton class requires other resources such as declaring the database connections in the other classes. Let’s discuss lazy instantiation with simple example as shown below using Microsoft Visual Studio 2013.
namespace SingletonDesignPattern
{
class Program
{
static void Main(string[] args)
{
Company obj1 = Company.GetInstance();
Company obj2 = Company.GetInstance();
}
}
public sealed class Company //declare class with sealed to avoid inheritance
{
private static Company objCompany;
//implement private constructor to avoid instantiation from outside
private Company()
{
}
//return the instance
public static Company GetInstance()
{
if (objCompany == null)
{
objCompany = new Company();
}
return objCompany;
}
}
}
As shown above Company class has GetInstance() method which returns the instance of the Company class. In the GetInstance() method we are comparing objCompany object getting created when it is null that means only for the first time even though we are calling Company class GetInstance() method multiple times.
The above type of Lazy instantiation is suitable single threaded applications, not for multi-threaded applications. This is because in multi-threaded applications if both threads are calling GetInstance() method same time and both threads are comparing objCompany with null at same time, then instance for the singleton class (here Company) get created two times which is not suitable for Singleton design pattern. To avoid this, we have to lock the instance creation for second thread until first thread completes its action as shown below.
namespace SingletonDesignPattern
{
class Program
{
static void Main(string[] args)
{
Company obj1 = Company.GetInstance();
Company obj2 = Company.GetInstance();
}
}
public sealed class Company //declare class with sealed to avoid inheritance
{
private static Company objCompany;
private static object _objLock = typeof(Company);
//implement private constructor to avoid instantiation from outside
private Company()
{
}
//return the instance
public static Company GetInstance()
{
lock (_objLock)
{
if (objCompany == null)
{
objCompany = new Company();
}
return objCompany;
}
}
}
}
As shown above we lock the instance creation in GetInstance() method using lock keyword until first thread completed. Only one thread can execute at a time if we lock the operation even though it is multi-threaded applications.
Eager Instantiation:
Eager instantiation is also same as lay instantiation, but in eager instantiation instance get created on the class load itself as shown below.
namespace SingletonDesignPattern
{
class Program
{
static void Main(string[] args)
{
Company obj1 = Company.GetInstance();
Company obj2 = Company.GetInstance();
}
}
public sealed class Company //declare class with sealed to avoid inheritance
{
private static Company objCompany = new Company();
//implement private constructor to avoid instantiation from outside
private Company()
{
}
//return the instance
public static Company GetInstance()
{
return objCompany;
}
}
}
As shown above instance objCompany created on the Company class load itself. Eager instantiation is suitable for both single threaded & multi-threaded applications, but memory gets wasted if the singleton class not getting called.