Design Pattern articles in this series are listed below:
Design Patterns - An Overview
Design Patterns – Using the Strategy Pattern in C#
Design Patterns – Using the Singleton Pattern in C#
Design Patterns – Using the Adapter Pattern in C#
Design Patterns - Using the Facade Pattern in C#
Design Patterns - Using the Composite Pattern in C#
Design Patterns - Using the Decorator Pattern in C#
Design Patterns - Using the Abstract Factory Pattern in C#
Design Patterns – Using the Builder Pattern in C#
Design Patterns - Using the Observer Pattern in C# (Events and Delegates)
Design Patterns – Using the Chain of Responsibility Pattern in C#
Design Patterns – Using the State Pattern in C#
Design Patterns – Which to use When? Take the Quiz!
What is a Singleton Pattern?
Singleton Pattern belongs to the category of Creational Patterns. If you recall from the Overview article, the Creational Patterns are the subset of Design Patterns that encapsulate the logic of object creation. In a Singleton Pattern, there is a class (Singleton class) that ensures that only a single instance of itself can be created. It also provides a global point of access to this instance. So, irrespective of where in your code base this class is instantiated, you will always get access to the same instance.
Let’s consider a real world example to make this concept clear. Consider an application that generates different types of reports using different methods. The Reporting class also has a counter that maintains the number of reports generated irrespective of method is used. This is a perfect example of a Singleton Pattern (we will implement the code later). When one is faced with a business problem like this, it’s really tempting to simply create an instance of the reporting class as a static global variable. Though this works, this does not guarantee that the instance of the class is created only once. In the Singleton pattern, the responsibility of ensuring that there is a single instance of the class lies on the Singleton class and not on the client that consumes the Singleton.
Let’s take a look at the ReportingSingleton Singleton class
public class ReportingSingleton
{
private static ReportingSingleton instance = new ReportingSingleton();
public int NumReportsGenerated { get; set; }
private ReportingSingleton() { }
public static ReportingSingleton GetInstance()
{
return instance;
}
}
The first thing you would note is that the constructor is private, so the client cannot instantiate this class directly. This is the main intent of the Creational patterns as they encapsulate the logic of object creation. So, how do you use this class? By using the snippet below.
ReportingSingleton singleton1 = ReportingSingleton.GetInstance();
As I noted earlier, our Reporting application has a counter that maintains the number of reports generated so far. This is done by the NumReportsGenerated property. Let’s take a look at the full client implementation
class Program
{
static void Main(string[] args)
{
GenerateReportByMethodA();
GenerateReportByMethodB();
}
private static void GenerateReportByMethodB()
{
ReportingSingleton singleton1 = ReportingSingleton.GetInstance();
singleton1.NumReportsGenerated++;
Console.WriteLine(String.Format("Number of reports generated so far : {0}", singleton1.NumReportsGenerated.ToString()));
}
private static void GenerateReportByMethodA()
{
ReportingSingleton singleton2 = ReportingSingleton.GetInstance();
singleton2.NumReportsGenerated++;
Console.WriteLine(String.Format("Number of reports generated so far : {0}", singleton2.NumReportsGenerated.ToString()));
}
}
There are 2 different methods to generate reports. Each method instantiates the ReportingSingleton class and the class has the responsibility of ensuring there is always a single instance. When you run this program, you will get the following output.
The implementation in Approach 1 would be an issue in multithreaded environments. Consider a Reporting service that spawns multiple threads and each thread calls the GenerateReportByMethodA() or GenerateReportByMethodB(). The second approach uses lazy initialization – the class is not created until it is needed.
public class ReportingSingleton
{
private static ReportingSingleton instance = null;
public int NumReportsGenerated { get; set; }
private ReportingSingleton() { }
public static ReportingSingleton GetInstance()
{
lock (typeof(ReportingSingleton))
{
if (instance == null)
{
instance = new ReportingSingleton();
}
return instance;
}
}
}
The difference between Approach 1 and Approach 2 is in the implementation of GetInstance() method. Note the use of the lock keyword. In multithreaded applications, there is a concept of a Critical Section. A Critical Section is a block of code that can be accessed only by 1 thread at any time. In C#, the critical section is implemented using the lock keyword. The thread that is accessing the critical section locks the code, executes the statements and unlocks so that other threads can access it.
Physical Model – Class Diagram
The class diagram is very simple. The GetInstance() method is the crux of this pattern.
The Singleton pattern is one of the simpler design patterns that involves only one class that is responsible to create only one instance of itself. If you enjoyed this article, check out other Design Pattern articles and do not forget to subscribe to the RSS feed.