Please navigate to the bottom of the page for Table of Contents

Saturday, May 21, 2011

Simple Patterns: Singleton Pattern

Design patterns offer proven ways to solve common architectural problems. There are many out there and it’s probably not reasonable to expect a candidate to know them all. However, depending on the years of experience a candidate has, they should be able to tell you one or two they have used in the past and more importantly why it’s useful to use a particular pattern.

Now, let’s start with the singleton pattern.

The singleton pattern enforces that one and only one instance of a class will ever exist within an application. This is relatively easy to do.

  1. Make all constructors of the class private.
  2. Create a private static member that’s of the same type of the class.
  3. Create a public static member that returns and instance of that class.

When the static method is called, first check if the private member that’s of the same type of the class is initialized. If it isn’t, do so. Then return that member to the caller. Easy right?

public class PaymentService
{
// the only instance that can be initialized
private static PaymentService _Instance;

// marked as private so no other classes can call the constructor
private PaymentService()
{ }

// only public way of initializing the PaymentService class
public static PaymentService GetInstance()
{
// has the instance been intialized yet?
if (_Instance == null)
{
// no - so lets do it
_Instance = new PaymentService();
}

return _Instance;
}
}



This is simple and works well. If you are writing a multi-threaded app though, this won’t work. It’s not thread safe. Don’t worry though. It’s a simple enough to fix. All you need to do is obtain a lock on a common object before initializing the instance. Locking a common object blocks any other threads from accessing that code block until the current thread is done. Using this approach ensures that no other threads access the single instance while it’s being initialized.

 

public class PaymentService
{
private static object _SyncRoot;
private static PaymentService _Instance;

private PaymentService()
{ }

public static PaymentService GetInstance()
{
if (_Instance == null)
{
// obtain lock so no other threads can access it until the current thread is done
lock (_SyncRoot)
{
// is it still null? another thread may have initialized _Instance before
// the current thread obtained the lock
if (_Instance == null)
{
_Instance = new PaymentService();
}
}
}

return _Instance;
}
}

2 comments:

  1. Nice article. If I execute the above code, I got the exception of type Null Reference Exception of line lock(_SyncRoot).

    Can you please tell me how to sort it out this issue?

    ReplyDelete
  2. It ought to be:
    private static object _SyncRoot = new object();

    ReplyDelete