Gang of Four (GOF) Design Patterns
page 1 of 8
Published: 05 Jun 2006
Unedited - Community Contributed
Abstract
In this article we will be taking a look at several Gang Of Four (GOF) design patterns with the help of code samples.
by John Spano
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 39031/ 122

Implementing the Singleton Design Pattern in .NET

Level:  Intermediate to Object Oriented Programming

Design Patterns are a very useful programming concept that is often forgotten about in the heat of a programming project.  Design Patterns are basically code design templates that have been perfected over the years by many different programmers and architects.  They represent repetitive design concepts that do not differ much.

One of the most famous design pattern books is called Design Patterns – Elements of Reusable Object Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides.  They are collectively known as the Gang of Four (GOF) and the book is commonly known as the GOF book.  I highly recommend this book as you learn object oriented programming.  It will start to make you think in patterns, which is essential to software.  Every application follows some similar concepts and patterns.

Many programming tasks are standard for each software project.  There are many times when you want a single instance of an object throughout the entire application.  Enter the Singleton design pattern.  This pattern limits an object to one instance in the entire application and returns that instance when called on.

Here is a simple working singleton class.

Listing 1

using System;
namespace Singleton
{
  public class Singleton
  {
    private static Singleton _instance = null;
 
    private Singleton(){}
 
    public static Singleton Instance()
    {
      if (_instance == null)
      {
        _instance = new Singleton();
      }
      return _instance;
    }
 
  }
}

Let us go over the code to see what happens.  First we create a class named Singleton.  It has a single member variable of type Singleton named _instance that is initialized to null.  This is the one instance of the class that all of our programs will use.  We make the constructor of the class private so that programs cannot create instances of the class directly.

The one function created for the class is named Instance and returns an object of type Singleton.  In the function we simply check to see if the internal variable is null, and if so create a new one.  This instance is then returned.

To verify our code the following can be run.

Listing 2

Singleton S1; 
Singleton S2; 

S1 = Singleton.Instance(); 
S2 = Singleton.Instance(); 
MessageBox.Show(S1.Equals(S2).ToString());

This will show true in the message.

The above code is fine for single threaded applications.  Now we will examine a thread safe version of the singleton.

Listing 3

using System;
using System.Threading;
 
namespace Singleton
{
  public class MultiSingleton
  {
    private static volatile MultiSingleton_instance = null;
 
    private MultiSingleton(){}
 
    public static MultiSingleton Instance()
    {
      if (_instance == null)
      {
        lock(typeof(MultiSingleton))
        {
          if (_instance == null)
          {
            _instance = new MultiSingleton();
          }
        }
 
      }
      return _instance;
    }
 
  }
}

This version of the singleton patterns is safe for multithreaded applications.  Let us examine the code to see what has changed.  There are only two significant changes: the definition of the instance variable and the lock work in the function.

The definition of the _instance variable has added the volatile keyword.  This is to ensure that the compiler does not do any memory optimizations on our variable by reordering our code in the function.  Without the volatile keyword the compiler might decide to remove the double check in the function.

The function can seem confusing at first, but makes sense after looking at it.  A double check is used to see if the instance variable is null.  We do this because no two threads would ever pass both conditions at the same time.  If the inner check was left out, two threads could run the null check at the same time.  Both would pass so both threads would then obtain the lock and create a new instance of the singleton.  The inner check prevents the second thread from creating the instance, since it would not be null after the first.  This brings up the point: Why not we just write it like the following then?

Listing 4

public static MultiSingleton Instance()
{
  lock(typeof(MultiSingleton))
  {
    if (_instance == null)
    {
      _instance = new MultiSingleton();
    }
  }
  return _instance;
}

This code would work fine and be perfectly thread-safe. We do not use the above because the lock is always entered.  This is not as fast as the previous double check code where the lock is avoided when the instance is not null.

The singleton is a very common design pattern.  I have kept the code shown as close as possible to the GOF book’s implementation of the pattern.  There are other ways to write a singleton in .NET, but the GOF implementation is one of the most common throughout other languages.  If you understand patterns and remember their names, it gives you the ability to converse with many other programmers on the same level.   If an architect calls for a singleton, that is what will be asked for.  The architect will not ask for a single instance of this class throughout the application.


View Entire Article

User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-10-09 2:37:46 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search