Saturday, December 20, 2008

Design Pattern - Singleton

Before we move to Singleton pattern, first we should know what is instantiation and how it will play main role in Singleton.

Please refer my previous post for basic information about Design Pattern if you needs.

Instantiation means creating an object using a class as a template. There are two approaches to instantiation:
  • Lazy instantiation
  • Eager instantiation

Lazy instantiation : a class is not instantiated until a request is made via the Singleton.Instance() method.
if (singleton == null)
{
singleton = new Singleton(); // lazy instantiation
Console.WriteLine ("Singleton instantiated");
}

This code is quite simple. If singleton is null, then the Singleton object has not yet been instantiated. And, if not, it is instantiated with the new operator. This is only done once; because, the next time the code is called, singleton will not be null.

Eager instantiation is still lazy, it will run the initializers whenever the class is instantiated or another static member is accessed.

public sealed class Singleton
{

//private static Singleton singleton;
private static readonly Singleton singleton = new Singleton(); // eager instantiation

static Singleton()
{
Console.WriteLine ("Singleton instantiated");
}

private Singleton() {} // private constructor

public static Singleton GetInstance()
{
//if (singleton == null)
//{
// singleton = new Singleton();
// Console.WriteLine ("Singleton instantiated");
//}
return singleton;
}
}

The only differences between this eager code and the previous lazy example is that Singleton is instantiated in the static initializer instead of in the Singleton.Instance() method; and, there is a static constructor. However, this implementation is thread safe.


Now we will move to singleton.

Singleton is a design pattern used to restrict the instantiation of a class to one object. It is one of the most used and well know design patterns in programming.

For an example, you may need a class that will contain the user information across the system, there is no need to create several instances of this class. The explanation of this will be given in this little sample below:

Step 1. DesignPatternTest.aspx

<%@ Page Language="C#" AutoEventWireup="true" Codebehind="DesignPatternTest.aspx.cs"
Inherits="DesignPatternTest.SingletonSample" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Singleton</title>
</head>
<body>
<form id="form1" runat="server">
<div>
See the above Singleton output
</div>
</form>
</body>
</html>

Step 2. DesignPatternTest.aspx.cs
using System;

namespace DesignPatternTest
{
public partial class SingletonSample : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Constructor is protected
// Prevented from using 'new' keyword
Singleton s1 = Singleton.Instance();
Singleton s2 = Singleton.Instance();

if (s1 == s2)
Response.Write("s1 & s2 are the same instance");

s1.x = 100;
Response.Write("<br>s1.x=" + s1.x);

s2.x = 200;
Response.Write("<br>s2.x=" + s2.x);

// Updates to x are updating same instance
Response.Write("<br>s1.x=" + s1.x);
Response.Write("<br>s2.x=" + s2.x);

}
}

public class Singleton
{
// Variable
public int x = 0;

// Fields
private static Singleton instance;

// Empty Constructor
protected Singleton() { }

// Methods
public static Singleton Instance()
{
// Uses "Lazy initialization"
if (instance == null)
instance = new Singleton();

return instance;
}
}
}

See the output

Singleton can be used in many situations, for samples.
  • Caches
  • Loggers
  • Thread pools
  • Dialog boxes
  • Device drivers
Last but not least, singleton is a class which permits itself to be instantiated only once.

  • Has a private or protected constructor with no parameters.
  • Has a single, global means of access via a static method.
  • Cannot be subclassed nor instantiated with the new operator.
  • Uses lazy instantiation

Happy Coding!!!