Singleton Design Pattern

In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object.  This pattern ensures that a class has only one instance and provides a global point of access to it. This is considered of the the simplest  design pattern.

When to Use Singleton Design Pattern
  • There must be one and only one instance of a class;
  • The class must be accessible to clients;
  • The class should not require parameter as part of its construction;
  • and when creating the instance that is expensive, a Singleton can improve performance.
Example:
  • Accessing  to a File System (Logger, Database);
  • Accessing to a Shared Resources
  • Log-in Credentials
Problems on Singleton Design Pattern

Problems Description
Anti-pattern It violates the Single Responsibility Principle. It introduces global state that spans all over the application. 
Not thread safe The basic implementation of Singleton is not thread safe. Especially in web application. Locking the resource/singleton before instantiating would solve the problem.
Difficult to test Test doubles cannot be implemented. To test it, you need to test the actual class.

The UML Class Diagram


Class/Interface Description
Singleton A private class which is responsible for creating and maintaining its own unique instance.

Example
The sample code presented here is a File Logger sample that supports thread safe. A test to insure that only one instance will be created is also provided in this code. 

Download Source Code


The Project Structure


The Singleton File Logger UML Class Diagram

File Logger Mapping on Singleton Design Pattern
Singleton Design Pattern Singleton File Logger 
Singleton FileLogger

The Codes

FileLogger.cs
using System;
using System.IO;
namespace SingletonDesignPattern.Singleton
{
class FileLogger
{
private static FileLogger _instance;
private static System.IO.StreamWriter TextFile = new System.IO.StreamWriter(Directory.GetCurrentDirectory() + "\\Log.txt", true);
private static object lockThis = new object();
private FileLogger() { }
public static FileLogger Instance
{
get
{
//This will ensure the thread safe
lock (lockThis) {
Console.WriteLine("Singleton invoked.");
if (_instance == null)
{
_instance = new FileLogger();
Console.WriteLine("Singleton Initialized.");
}
return _instance;
}
}
}
public void WriteToFile(string text)
{
Console.WriteLine("Writing to File...");
TextFile.WriteLine(text);
}
public void CloseFile()
{
TextFile.Close();
TextFile.Dispose();
}
}
}

Program.cs
using SingletonDesignPattern.Singleton;
namespace SingletonDesignPattern
{
class Program
{
static void Main(string[] args)
{
var fileLogger = FileLogger.Instance;
fileLogger.WriteToFile("Singleton is awesome for Performance.");
fileLogger.WriteToFile("More from Singleton..");
//Test for to see if another instance will be created.
//Singleton Initialized should be printed twice.
var fileLogger1 = FileLogger.Instance;
fileLogger1.WriteToFile("Using another instance...");
fileLogger1.WriteToFile("More from another instance.");
fileLogger.CloseFile();
fileLogger1.CloseFile();
}
}
}

The Output


If we look closely on the output, the FileLogger was invoke twice but it is only initialized once. Meaning there is only one instance despite assigning to different variables.

Ok. Thank you! Hope this is helpful.