Design Pattern For Beginners - Part-1: Singleton Design Pattern

Introduction

Welcome to the Design Pattern For Beginners article series. Here are a few parts; I will discuss various design patterns (in other words, a few of the most popular) targeting beginners. I will discuss most of the patterns in my own style and words. And before starting any pattern, we will try to find its basic need. So, let's begin our journey with a very nice quote.

"It's easy to walk on water and develop software from specifications when both are frozen."

Hey, that's not mine!! My poor memory says I read it somewhere in someone's blog. And I have forgotten where I read it. And I have forgotten where I read it. Please put a few keystrokes in the comments section if anyone has any information.

Anyway, let's return to the subject of this article. It's easy to develop software from specifications and when the requirements are constant. But by nature, people are not happy with the constant and fixed needs. (Yes, that's why language designers created variables! Ha... Ha...)

And here, design pattern come into play. If we implement a good design pattern we need not worry much when new requirements are added to the old ones. And here lies the importance of design patterns.

As I said earlier, this article series is targeted at young developers. If you fall in this category, then this introduction is enough to make explain "Why a design pattern is essential."

I am grateful to "Shivaprasad koirala, Sir"; from your video tutorial, I have heard the word "Design pattern" for the first time. Many thanks for providing the first of my design pattern journey.

Ok, that's a long introduction. Today let's start with a pervasive and easy design pattern called the "Singleton Design Pattern."

What is Singleton Design Pattern?

Let's learn why the Singleton Design Pattern is implemented. And then, we will see how to implement it in C#.

Basic need: Think there is a hit counter in any web application. (I know you have already seen many examples like this). Now, when a visitor hits a web application, it will increase by one. This is one scenario where we can implement the Singleton Design Pattern.

Or think about another situation where you want to share a single instance of a class across various threads.

We can implement the singleton pattern in one of two ways.

1. Make the constructor private so that  o one can create an object of the singleton class

Have a look at the following code to understand the basic concept.

using System;  
using System.Collections;  
using System.Data.SqlClient;  
namespace Test1  
{  
    class singleTon  
    {  
        public static int counter = 0;  
        private singleTon()  
        {  
            //Private constructor will not allow create instance  
        }  
        public static int Returncount()  
        {  
            return counter;  
        }  
        public static void IncreaseCount()  
        {  
            counter++;  
        }  
    }  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            //singletone design pattern  
            Console.WriteLine("Before increase : " + singleTon.counter);  
            singleTon.IncreaseCount();  
            Console.WriteLine("After Increase:" + singleTon.counter);  
            Console.ReadLine();  
        }  
    }  
} 

Here is some sample output.

Ok, you may think, Sourav!! We are not creating any object in the above example, but in the introduction, why did you say we will create a single object and share it across threads?  Yes, we will get to that in the folloing example but believe me, it's also a design style of a singleton pattern. Ultimately, we are sharing a single c ass across various threads (though we did not implement any multi-threading concept). Oh! Are you worried about deadlock problems? Ok, let's see the following example.

 how to Create a single instance and share it across threads?

In this example, we will implement a singleton class so that only one instance of that class is possible, and if the second request comes, then it will return the previously created object only. Have a look at the following code.

using System;  
using System.Collections;  
using System.Data.SqlClient;  
namespace Test1  
{  
    public sealed class singleTon  
    {  
        public Int32 Data = 0;  
        private static singleTon instance;  
        private static object syncRoot = new Object(); //For locking mechanism  
        private singleTon() { } //Private constructor  
        public static singleTon Instance //Property  
        {  
            get  
            {  
                if (instance == null)  
                {  
                    lock (syncRoot)  
                    {  
                        if (instance == null)  
                            instance = new singleTon();  
                    }  
                }  
                return instance;  
            }  
        }  
    }  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            //singletone design pattern  
            singleTon s = singleTon.Instance;  
            s.Data = 100;  
            Console.WriteLine("Data of S object : " + s.Data);  
            singleTon s1 = singleTon.Instance;  
            Console.WriteLine("Data of S1 object : " + s.Data);  
            Console.ReadLine();  
        }  
    }  
}

He e we have defined a member called instance within the singleton class. And within the class property (yes, it's also an Instance, but don't be confused), we are checking whether the instance is null using a condition in an if statement. If it is null, then no instance is crated of this class, if it is not, then an instance has already been created, and it's time to return the previously created instance.

Here is a sample output of this example.

Now, we will analyze the Main() function here. Have a look at the following code.

singleTon s = singleTon.Instance;  //First instance  
s.Data = 100; //Data of first instance           
Console.WriteLine("Data of S object : " + s.Data);  
singleTon s1 = singleTon.Instance;  //Again request and return old instance  
Console.WriteLine("Data of S1 object : " + s.Data);  //Show data of old instance  
Console.ReadLine();

In the first two lines, we create the first instance of the singleton class and set the data value. Now in the fourth line, we are again requesting a new object of the singleton class, but there is no chance of getting a new one (since this is our main target), and from the property, the old one is returned. Yes, that's why in the first object, we have set Data=100, and it has been reflected in the second instance, proving that no new object has been created.

Conclusion

It's time to summarize my article. By habit, in my previous "Best performance of C# code" series of articles, I wrote something for my dear respected Sam (Who is an enthusiastic editor and critic of the C# article). Sam is waiting for your comment, and let's improve my way of learning. Make me more serious before writing t e following code sample for my next article.

Continue Reading