Learning Design Patterns - Singleton

A while ago now I bought this book on design patterns. At first glance, this book may seem a little silly, childish even, because of all the cartoonish thought bubbles on amusing old photographs and the crosswords and such. After reading the introduction that explained how making learning fun and interesting, and how they were going to trick my brain into paying attention to an otherwise dull subject, and how they sneaked in repetition and other memory inducing tricks, it started to make a lot of sense to me. Even though this book is targeted more at Java developers and I am a .Net developer, it is general enough and explains the concepts well enough that I have no problems understanding it.

This is the first post in my new series on learning design patterns. To say it another way, I am going to be learning these patterns along the way, so any helpful comments and corrections from the more experienced would be appreciated - just be kind!

To start, I figured I would select the classic and deceptively simple Singleton pattern. I guess I could start by writing a monologue about why patterns are important, but I'll leave that one to the academics; I just want to broaden my horizons and am more interested in application. Besides, I know a guy who got a great job in part because he knew how to write a Singleton pattern during his interview (not a bad interview question, I'd say).

What is it?
The Singleton pattern is intended to create one and only one instance of an object that can be accessed globally across an application.

Where is it used?
The Singleton pattern works well in many situations. Common uses include managing connection or thread pooling, application configuration settings, logging, dialog boxes, incremental or other counters, and device drivers.

But why?
Why not just create global variables or static methods? The Singleton pattern is a design convention, a best-practice of sorts and generally it would be better to pick it over the other two methods. Singleton gives you a global access point like a global variable, but is intended to reduce overhead by not initiating the object until it is called, unlike global variables that would be initiated at startup even if they are never used and guarantees that there is only one instance in memory.

OK, and how is it implemented?
Have you ever seen those kooky UML diagrams for design patterns? Crap, I'd have better luck baking a German Chocolate Cake from a recipe in German than writing code based on one of those. Suffice it to say, I have to spell it out instead.

The key ideas are: 1) Use a private constructor so that only the class itself can initiate itself, which will allow it to regulate itself. 2) Declare a private static variable of the same type as the class itself to hold a reference to the object in memory. 3) Create a public method that checks to see if the object exists in memory, if so, return a reference, if not create it first then return a reference. 4) Add other code as needed, but don't allow sub classing (which is impossible anyway since the constructor is private). 5) When it comes to threading, be super careful; it is easy to goof up and allow two instances of the object to exist.

//general example from the book; Java?
public class Hermit {
	private static Hermit singleInstance;
	private Hermit() {}
	public static Hermit getInstance() {
		if (singleInstance == null) {
			singleInstance = new Hermit();
		}
		Return singleInstance;
	}
}

//Direct port to C#
class Hermit 
{
  //prevent optimization reordering with volatile keyword
  private static volatile Hermit singleInstance = null;
  protected Hermit() {}
  public static Hermit getInstance() {    
    if (singleInstance == null) {
	// double-check lock for thread safety and to 
	// reduce overhead if instance exists
            lock (typeof(Hermit)) {
                if (singleInstance == null) {
                    singleInstance = new Hermit();
                }
            }
        }
        return singleInstance;      
    }
}

//Simplified C# code that relies on .Net Framework's intrinsic abilities
sealed class Hermit  //sealed=not inheritable
{
   private Hermit() {}
   public static readonly Hermit getInstance = new Hermit();
   //.Net Framework guarantees thread safety on 
   //static type initialization, and only initializes static
   // properties when the method is first called.
}

Further Reading