Singleton Pattern


Most of you will have heard of this pattern. It is the simplest and a popular pattern among the 23 design patterns.

Challenge

You are working on an application which requires Logging information into a file named Application.Log. The logging is managed by a class named LogManager. The LogManager through its constructor keeps a lock on the File.

The LogManager instance an be created throughout the application and it will result in Exceptions. Above that there is only instance requirement for the LogManager class.

The above problem can be solved using Singleton Pattern.

Definition

"Ensure a class only has one instance, and provide a global point of access to it."

Implementation

To implement the specification above we have to perform the following:

  • Make the Constructor Private and Create only 1 Instance
  • Create a Static Property to Access the Instance

Following is the modified class definition according to Singleton Pattern.

SingPatt1.gif

The following is the code contained in LogManager class.

public class LogManager
{
   
private static LogManager _instance;

    public static LogManager Instance
    {
       
get
        {
           
if (_instance == null)
                _instance =
new LogManager();

            return _instance;
        }
    }

    private LogManager()  // Constructor as Private
    {
        _fileStream =
File.OpenWrite(GetExecutionFolder() + "\\Application.log");
        _streamWriter =
new StreamWriter(_fileStream);
    }

    private FileStream _fileStream;
   
private StreamWriter _streamWriter;

    public void WriteLog(string message)
    {
       
StringBuilder formattedMessage = new StringBuilder();
        formattedMessage.AppendLine(
"Date: " + DateTime.Now.ToString());
        formattedMessage.AppendLine(
"Message: " + message);

        _streamWriter.WriteLine(formattedMessage.ToString());
        _streamWriter.Flush();
    }

    public string GetExecutionFolder()
    {
       
return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    }
}

You can see that the constructor is private here.  As it is private outside classes cannot create instance of LogManager.

    private LogManager()  // Constructor as Private
    {
        --
    }


You can see the new Instance property which is static. It also ensures only one instance is created.

    public static LogManager Instance
    {
       
get
        {
           
if (_instance == null)
                _instance =
new LogManager();
 
            return _instance;
        }
    }

For invoking the write method we can use the following code:

LogManager.Instance.WriteLog("Test Writing");

Following image depicts the Number of Instances in Singleton and Normal Scenario.

SingPatt2.gif

The advantage of using Singleton is listed below:

  • Instance Reuse makes Effective Memory Management

  • File Locking Overheads are Avoided

The limitations of Singleton are listed below:

  • Making Constructor as Private impose Restrictions

  • More Overheads in Multi-threaded usage (But Thread Safe in .Net)

Summary

In this article we have seen what is Singleton pattern and a possible implementation of it using C#.NET. Multiton is another pattern which is often compared with Singleton.
 


Similar Articles