Singleton Design Pattern and It’s Advantages


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.

  • We should implement private constructor for that class to avoid the object instantiating from outside of that class. Singleton class should not have any other constructor other than private constructor that means class should not have any non-private constructor.


  • Class should be declared with sealed keyword to avoid the inheritance from other class. If we don’t have sealed keyword, other classes can inherit this class and can maintain multiple instances of that class through inherited class.


  • Class should be declared as public to make it available for other classes.


  • Class should have one public variable or public method to return the instance of the 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.