KnowDotNet

Design Patterns - Singleton Pattern

Practical Design Patterns

by Les Smith

Have you learned Design Patterns?  You probably need it on your resume, and once you start to use Design Patterns you will find that your code structure is improving.  This article will start with the simplest pattern.  I was once blindsided in an interview with questions on Design Patterns.  I tried to bluff my way through it by saying that Design Patterns were basically the way good programmers had always developed programs.  That wasn't good enough!  From that point on, I determined that I should look into learning Design Patterns.  I don't like getting caught twice in the same trap.

Although I contract in a company with numerous developers, I hear almost no talk about Design Patterns, and basically witness no use of them.  The shop, where I currently contract, is a VB.NET shop.  I don't know if the failure to talk about and use design patterns has anything to do with them using VB.NET instead of C# or not.  Although I use C# as well as VB.NET, I have been a VB kinda of a guy for most of my PC development years.  Therefore I can safely say that many times I have found that VB developers get so busy with developing, that they sometimes lag behind C# developers in venturing into new areas.  I may catch heat for saying this, but because VB and especially VB.NET has always done so much for developers that maybe we didn't think we had to go beyond what the basic platform provided.  

Enough philosophy!  Let's jump into Design Patterns.  Basically, the "Gang of Four"
GoFcatagorized Design Patterns years ago into three basic categories; creational, behavioral, and structural.  I am going to begin with creational patterns and with the simplest of those design patterns, the Singleton pattern.  The objective of the Singleton pattern is to ensure that a class has only one instance at a time and to provide a global place in which to reference it.

Although a very simple pattern, there are numerous places in which to use it.  The Singleton pattern  has three simple objectives:

1. Hide the default constuctor so that the class cannot be instantiated from outside of the class.
2. Create a custom constructor which returns the single instance of the object, once it is instantiated.
3. Add a shared variable referencing the the single instantiated instance of the class.

The following code shows the shell of the code for a Singleton pattern that I used recently.

Public Class MonitorBatches

  
Private Shared singleInstance As MonitorBatches
  
''' <summary>
   ''' Hide the default constructor so that the class cannot
   ''' be instantiated from outside the class.
   '''
   ''' <remarks>
   Private Sub New()
      ' you can put code in here as it will be executed when instantiated.

  
End Sub

   ''' <summary>
   ''' Create a custom constructor that the instantiator must
   ''' call to create or get the singleton instance of the class.
   ''' It guarantees that one and only one instatnce can ever be created.
   '''
   ''' <returns>
   ''' <remarks>
   Public Shared Function GetSingleton() As MonitorBatches
      
If singleInstance Is Nothing Then
         singleInstance = New MonitorBatches()
      
End If
      Return singleInstance
  
End Function

   ''' <summary>
   ''' DoNothing method is simply a public method that can be referenced
   ''' only after the class is instantiated.
   '''
   ''' <remarks>
   Public Sub DoNothing()

  
End Sub
End
Class


The code shown next demonstrates the main module code in this console application that instantiates an instance of the object and uses it.

Figure 2 - Main Module Code for creating and using the object.

Module Module1

  
Public Sub Main()
      
' get instance of the object
      Dim mb As MonitorBatches = MonitorBatches.GetSingleton()
      
' now, call a method in the class
      mb.DoNothing()

      
' trying to get another instance will get the same object as
      ' previously obtained in mb...
      Dim mb2 As MonitorBatches = MonitorBatches.GetSingleton()

      
' attempting to create the object will result in a compile error
      ' "...New is not accessible because it is private...."
      ' therefore the following line of code will not compile.
      mb = New MonitorBatches

  
End Sub

End
Module

Regardless of the number of times and places that you get the instance of the the class, you will always get the same object.  That is why it is called a Singleton; there is only one possible instance of the class.

There is a caveat in using a Singleton.  If you are running a multi-threaded application, you must be careful that the class does not have unprotected global variables and you also need to protect the creation of the object if it is not already created.  In the code shown below I have protected  the custom constructor by the use of a Mutex.

   Public Shared Function GetSingleton() As MonitorBatches
      
' block other threads until the object is created
      block.WaitOne()

      
If singleInstance Is Nothing Then
         singleInstance = New MonitorBatches()
      
End If

      ' clear the block
      block.ReleaseMutex()
      
Return singleInstance
  
End Function

By the way if you hate VB.NET, here is the code for the C# Class.

public class MonitorBatches
{

  
private static MonitorBatches singleInstance;
  
/// <summary>
  
/// Hide the default constructor so that the class cannot
  
/// be instantiated from outside the class.
  
///
  
/// <remarks>
  
private MonitorBatches()
   {
      // you can put code in here as it will be executed when instantiated.

   }

  
/// <summary>
  
/// Create a custom constructor that the instantiator must
  
/// call to create or get the singleton instance of the class.
  
/// It guarantees that one and only one instatnce can ever be created.
  
///
  
/// <returns>
  
/// <remarks>
  
public static MonitorBatches GetSingleton()
   {
      
if (singleInstance == null)
        singleInstance =
new MonitorBatches();
      
return singleInstance;
   }

  
/// <summary>
  
/// DoNothing method is simply a public method that can be referenced
  
/// only after the class is instantiated.
  
///
  
/// <remarks>
  
public void DoNothing()
   {

   }

This has been a simple introduction to Design Patterns and the simpliest of patterns.  In future articles I will move into more complex and more useful Design Patterns.

Have you tried our newest product, Visual Class Organizer?  You'll be amazed how easy it is to keep the code in your code windows organized.  TRY IT FREE FOR 30 DAYS BY CLICKING HERE.



Ask a Question, or give your feedback on my articles or products by going to the KnowDotNet Forum or by clicking on My Blog.