SIGN UP MEMBER LOGIN:    
ARTICLE

Singleton Design Pattern

Posted by Srihari Chinna Articles | Design & Architecture October 26, 2010
This article talks about Singleton design pattern.
Reader Level:

What is Singleton Definition Pattern?

This is a very simple design pattern; let me tell you one thing, there are many design patterns that they are implicitly singletons.  I recommend understanding this one first before going through other patterns. 

There are many cases that we need only one instance of the object through-out the application, may be specific scope like user specific and the class should not allow the users or other classes creating object on their own. Apart from one instance, the same object should provide or control the creation of object and provide the instance to anyone who requires that object.

Standard definition is that: 'Ensure a class has only one instance, and provide a global point of access to it.'

Design

In the definition, the first part is 'Ensure a class has only one instance'. How can we say that there is only one instance? 

If and only if the same class is not creating himself and controlling the access to it we can't ensure that there is only one instance. So how to avoid issuing 'new' keyword on the object? Make the class default constructor as private. That's it; no one will be able to issue 'new' key word on your class.

public class MySingleton
{
    private MySingleton (){}
}

Now who will create the instance of the class? Declare a private variable of class type and initialize it at class scope.

public class MySingleton
{
    private MySingleton _mySingleton = new MySingleton ();
    private MySingleton ()
    {
    }
}

Now the question here is that unless the constructor is called this class scope variable will not be initialized, so what to do now? Something should be called in the class that will initialize or create the instance by calling the constructor. So we have to use a static method or property so that even without initializing the class can be used and in turn it will create an object and return for use. Make the private class scope variable as static, you know why right? If it is not static we can't call inside static method or property.

public class MySingleton
{
    private static MySingleton _mySingleton = new MySingleton ();
    private MySingleton (){}
    public static MySingleton  GetInstance ()
    {
        return _mySingleton;
    }
}

Now what happens is, when we call static method, which is the private variable will initialize, when it is, the 'new' keyword will call the private constructor that's it. We have class object created.

As Instance method is Static which can't be overriden in the derived calls, as Static methods are not virtual.

Now there is problem here; what if two threads try to create an instance? There are many ways to implement this. One of it is here. Also remember if the variable is not fully initialized it should not be accessed. Here is the complete example.

public sealed class MySingleton
//volatile ensures that variable is fully initilized before accessing it.
private static volatile MySingleton _instance;
private static object lockObject = new object();
//private construct to avoid Newing the class
private MySingleton() { }
//double checking for multi threading
public static MySingleton Insatnce()
{
    if (_instance ==null)
    {
        //Allows only one thread to initialise the object
        lock(lockObject)
        {
            if (_instance==null)
                _instance = new MySingleton();
        }
    }
    return _instance;
}

Now you will say it is like a static class what is the difference? Basic difference is that a multithreaded environment maintains one instance per thread where as Singleton is one across threads. 

Another way of implementing the same pattern

public class Singleton
{
    // A static member to hold a reference to the singleton instance.
    private static Singleton instance;
    // A static constructor to create the singleton instance. Another alternative is to use lazy initialization in the Instance property.
    static Singleton()
    {
        instance = new Singleton();
    }
    // A private constructor to stop code from creating additional instances of the singleton type.
    private Singleton() { }
    // A public property to provide access to the singleton instance.
    public static Singleton Instance
    {
        get { return instance; }
    }
}

Let us see the Real Example

Requirement 

In one of my applications; we had requirement like showing address in two different formats. One format is like countries those have States will use one format and those countries that didn't have States use other format. But client didn't have data for all countries. If the states are available in the data bases then we need to show the State drop down or else don't Show and it is dynamic. Here the usage for state are high, States are accessed frequently based on the country code (Universal code).

Design Approach
  • States are accessed frequently.
  • Not sure when the states data will be available. 
  • Same information across the application has to be used by all the users.
  • Decided to use the Singleton with Parameterized by country code
  • Here instances are maintained same across the application based on the country code rather than the same instance. 
Code

public sealed class StateSingleton
{
    public string _countryCode;
    public ArrayList _states;
    private static object _object = new object();
    private static volatile HashSet<StateSingleton> _stateSingletonList = new HashSet<StateSingleton>();
    private StateSingleton(){}
    public static StateSingleton GetInstance(string countryCode)
    {
        StateSingleton instance = new StateSingleton();
        if (!isExists(countryCode))
        {
            if (instance != null)
            {
                lock (_object)
                {
                    if (instance != null)
                    {
                        instance._countryCode = countryCode;
                        instance._states = getStates();
                        _stateSingletonList.Add(instance);
                    }
                }
            }
        }
        else
        {
            lock (_object)
            {
                instance = _stateSingletonList.Where<StateSingleton>(a => a._countryCode == countryCode).Single();
            }
        }
        return instance;
    }
    private static bool isExists(string countryCode)
    {
        if (_stateSingletonList.Where<StateSingleton>(stateSingleton => stateSingleton._countryCode == countryCode).Count() > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    private static ArrayList getStates()
    {
        return new ArrayList {"a","b"};
    }
}

Compare with other patterns
  1. Abstract Factory, Builder, and Prototype can use Singleton in their implementation.
  2. Facade objects are often Singletons because only one Facade object is required.
  3. State objects are often Singletons.

Login to add your contents and source code to this article
share this article :
post comment
 
Become a Sponsor
PREMIUM SPONSORS
  • Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites - Click Here!
    Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor