Exploring the Singleton design pattern

Use the Singleton design pattern to create classes of which only one instance can exist

Singleton class

Singleton class

Design patterns are solutions to recurring problems and complexities in software design and are classified into three distinct categories: creational, structural, and behavioral. While creational patterns are used to create and manage the mechanism of creating instances of classes, structural patterns are those that are used to define the structure of types and their relationships -- these help to realize the relationships among the entities. Behavioral design patterns are those that deal with object collaboration and delegation of responsibilities among them.

The Singleton Design pattern is a creational design pattern that states that one and only one instance of a class can exist throughout the lifetime of an application. In this article, I will present an overview of the Singleton design pattern and show how we can implement it using the C# programming language.

Should I use a static class or a Singleton class?

A static class is one that can only have static members. You cannot inherit or instantiate a static class. Unlike static classes, Singleton classes can be inherited, can have base class, can be serialized and can implement interfaces. You can implement Dispose method in your Singleton class. So, static classes are much less flexible compared to Singleton classes.

The choice between a Singleton class and a static class entirely depends on whether or not you need an instance for your class and the advantages that a Singleton class provides. Static classes can only have static members are these classes cannot be inherited -- these classes are sealed implicitly. While static classes are a good choice for storing helper methods, you can use a Singleton class to build a state manager class that can manage state (application state, cache or session, etc.) in your application. Another advantage of a Singleton class is that it can be initialized lazily or asynchronously. You can't do this with a static class -- it is initialized when it is loaded in the memory.

Implementing a Singleton class

Well, let’s now dig into some code. The following code snippet illustrates a Singleton class.

public class StateManager

{

   private static StateManager instance;

 

   private StateManager() {}

   public static StateManager Instance

   {

      get

      {

         if (instance == null)

         {

            instance = new StateManager();

         }

         return instance;

      }

   }

}

Note how the object of the StateManager class has been created. The static property Instance can be used to retrieve a reference to the instance of the StateManager class. The StateManager class is sealed to prevent inheritance and it has a private constructor so that no instance of it can be created. OK, but what about thread safety?

The following code listing shows a modified version of the StateManager class that has thread safety implemented.

public sealed class StateManager

{

   private static volatile StateManager instance;

   private static object lockObj = new Object();

   private StateManager() {}

   public static StateManager Instance

   {

      get

      {

         if (instance == null)

         {

            lock (lockObj)

            {

               if (instance == null)

                  instance = new StateManager();

            }

         }

         return instance;

      }

   }

}

The volatile keyword is used to ensure that the object is initialized prior to being accessed. This implementation is thread safe -- a check is made to see if an instance of the StateManager class has been created prior to creating the instance. Note that instead of locking on the typeof(StateManager) you should lock on a static object that is private to the StateManager class. This ensures that the potential risks of performance issues and deadlocks are eliminated.

The next version of our StateManager class implements lazy initialization using a nested class.

public sealed class StateManager

{

    private StateManager()

    {

    }

    public static StateManager Instance { get { return Nested.instance; } }    

    private class Nested

    {

        static StateManager()

        {

        }

        internal static readonly StateManager instance = new StateManager();

    }

}

You might not need full laziness in most cases unless your Singleton class needs to do some initialization that would be resource consuming and takes up a lot of time. Having said that I would prefer to use lazy initialization only if there are no resource consuming initialization operations needed in the class. Note that a static constructor is invoked when the class is instantiated or when a static member of the class is accessed.The explicit static constructor is used in the example earlier to inform the runtime not to mark the type (the StateManager class in this example) as beforefieldinit.

Our final version of the StateManager class is even better - it leverages the System.Lazy<T> type (available from .Net Framework 4) to make the laziness seamless and simple.

public sealed class StateManager

{

    private static readonly Lazy<StateManager> singleton =

        new Lazy<StateManager>(() => new StateManager());

     public static StateManager Instance { get { return singleton.Value; } }

    private StateManager()

    {

    }

}

You can learn more on Singleton design pattern and how it can be implemented in C# from this MSDN article.

This article is published as part of the IDG Contributor Network. Want to Join?

To comment on this article and other InfoWorld content, visit InfoWorld's LinkedIn page, Facebook page and Twitter stream.
From CIO: 8 Free Online Courses to Grow Your Tech Skills
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.