Singleton Pattern


Sample 1:

Singleton pattern falls under Creational Pattern of Gang of Four (GOF) Design Patterns in .Net. It is pattern is one of the simplest design patterns. This pattern ensures that a class has only one instance. In this article, I would like share what is Singleton pattern and how is it work?

What is Singleton Pattern?

Singleton pattern is one of the simplest design patterns. This pattern ensures that a class has only one instance and provides a global point of access to it.

Singleton Pattern – UML Diagram & Implementation

The UML class diagram for the implementation of the Singleton design pattern is given below:

The classes, and objects in the above UML class diagram are as follows:

  1. Singleton

    This is a class which is responsible for creating and maintaining its own unique instance.

C# – Implementation Code

  1. //eager initialization of singleton
  2. public class Singleton
  3. {
  4. private static Singleton instance = new Singleton();
  5. private Singleton() { }
  6.  
  7. public static Singleton GetInstance
  8. {
  9. get
  10. {
  11. return instance;
  12. }
  13. }
  14. }
  15.  
  16. ////lazy initialization of singleton
  17. public class Singleton
  18. {
  19. private static Singleton instance = null;
  20. private Singleton() { }
  21.  
  22. public static Singleton GetInstance
  23. {
  24. get
  25. {
  26. if (instance == null)
  27. instance = new Singleton();
  28.  
  29. return instance;
  30. }
  31. }
  32. }
  33.  
  34. ////Thread-safe (Double-checked Locking) initialization of singleton
  35. public class Singleton
  36. {
  37. private static Singleton instance = null;
  38. private Singleton() { }
  39. private static object lockThis = new object();
  40.  
  41. public static Singleton GetInstance
  42. {
  43. get
  44. {
  45. lock (lockThis)
  46. {
  47. if (instance == null)
  48. instance = new Singleton();
  49.  
  50. return instance;
  51. }
  52. }
  53. }
  54. }

Singleton Pattern – Example

Who is what?

The classes and objects in the above class diagram can be identified as follows:

  1. Singleton – Singleton class

C# – Sample Code

  1. /// <summary>
  2. /// The ‘Singleton’ class
  3. /// </summary>
  4. public class Singleton
  5. {
  6. // .NET guarantees thread safety for static initialization
  7. private static Singleton instance = null;
  8. private string Name{get;set;}
  9. private string IP{get;set;}
  10. private Singleton()
  11. {
  12. //To DO: Remove below line
  13. Console.WriteLine(“Singleton Intance”);
  14.  
  15. Name = “Server1”;
  16. IP = “192.168.1.23”;
  17. }
  18. // Lock synchronization object
  19. private static object syncLock = new object();
  20.  
  21. public static Singleton Instance
  22. {
  23. get
  24. {
  25. // Support multithreaded applications through
  26. // ‘Double checked locking’ pattern which (once
  27. // the instance exists) avoids locking each
  28. // time the method is invoked
  29. lock (syncLock)
  30. {
  31. if (Singleton.instance == null)
  32. Singleton.instance = new Singleton();
  33.  
  34. return Singleton.instance;
  35. }
  36. }
  37. }
  38.  
  39. public void Show()
  40. {
  41. Console.WriteLine(“Server Information is : Name={0} & IP={1}”, IP, Name);
  42. }
  43.  
  44. }
  45.  
  46. /// <summary>
  47. /// Singleton Pattern Demo
  48. /// </summary>
  49. ///
  50. class Program
  51. {
  52. static void Main(string[] args)
  53. {
  54. Singleton.Instance.Show();
  55. Singleton.Instance.Show();
  56.  
  57. Console.ReadKey();
  58. }
  59. }

Singleton Pattern Demo – Output

When to use it?

  1. Exactly one instance of a class is required.
  2. Controlled access to a single object is necessary.

Sample 2:

Singleton

 


 

Definition

Ensure a class has only one instance and provide a global point of access to it.

 

Frequency of use:
Medium high


 

UML class diagram

 


 

Participants

 

The classes and objects participating in this pattern are:

  • Singleton   (LoadBalancer)
    • defines an Instance operation that lets clients access its unique instance. Instance is a class operation.
    • responsible for creating and maintaining its own unique instance.


 

Structural code in C#

 

This structural code demonstrates the Singleton pattern which assures only a single instance (the singleton) of the class can be created.

  1. using System;

  2.  

  3. namespace DoFactory.GangOfFour.Singleton.Structural

  4. {

  5.   /// <summary>

  6.   /// MainApp startup class for Structural

  7.   /// Singleton Design Pattern.

  8.   /// </summary>

  9.   class MainApp

  10.   {

  11.     /// <summary>

  12.     /// Entry point into console application.

  13.     /// </summary>

  14.     static void Main()

  15.     {

  16.       // Constructor is protected — cannot use new

  17.       Singleton s1 = Singleton.Instance();

  18.       Singleton s2 = Singleton.Instance();

  19.  

  20.       // Test for same instance

  21.       if (s1 == s2)

  22.       {

  23.         Console.WriteLine(“Objects are the same instance”);

  24.       }

  25.  

  26.       // Wait for user

  27.       Console.ReadKey();

  28.     }

  29.   }

  30.  

  31.   /// <summary>

  32.   /// The ‘Singleton’ class

  33.   /// </summary>

  34.   class Singleton

  35.   {

  36.     private static Singleton _instance;

  37.  

  38.     // Constructor is ‘protected’

  39.     protected Singleton()

  40.     {

  41.     }

  42.  

  43.     public static Singleton Instance()

  44.     {

  45.       // Uses lazy initialization.

  46.       // Note: this is not thread safe.

  47.       if (_instance == null)

  48.       {

  49.         _instance = new Singleton();

  50.       }

  51.  

  52.       return _instance;

  53.     }

  54.   }

  55. }

  56.  

 

Output
Objects are the same instance


 

Real-world code in C#

 

This real-world code demonstrates the Singleton pattern as a LoadBalancing object. Only a single instance (the singleton) of the class can be created because servers may dynamically come on- or off-line and every request must go throught the one object that has knowledge about the state of the (web) farm.

  1. using System;

  2. using System.Collections.Generic;

  3. using System.Threading;

  4.  

  5. namespace DoFactory.GangOfFour.Singleton.RealWorld

  6. {

  7.   /// <summary>

  8.   /// MainApp startup class for Real-World

  9.   /// Singleton Design Pattern.

  10.   /// </summary>

  11.   class MainApp

  12.   {

  13.     /// <summary>

  14.     /// Entry point into console application.

  15.     /// </summary>

  16.     static void Main()

  17.     {

  18.       LoadBalancer b1 = LoadBalancer.GetLoadBalancer();

  19.       LoadBalancer b2 = LoadBalancer.GetLoadBalancer();

  20.       LoadBalancer b3 = LoadBalancer.GetLoadBalancer();

  21.       LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

  22.  

  23.       // Same instance?

  24.       if (b1 == b2 && b2 == b3 && b3 == b4)

  25.       {

  26.         Console.WriteLine(“Same instance\n”);

  27.       }

  28.  

  29.       // Load balance 15 server requests

  30.       LoadBalancer balancer = LoadBalancer.GetLoadBalancer();

  31.       for (int i = 0; i < 15; i++)

  32.       {

  33.         string server = balancer.Server;

  34.         Console.WriteLine(“Dispatch Request to: “ + server);

  35.       }

  36.  

  37.       // Wait for user

  38.       Console.ReadKey();

  39.     }

  40.   }

  41.  

  42.   /// <summary>

  43.   /// The ‘Singleton’ class

  44.   /// </summary>

  45.   class LoadBalancer

  46.   {

  47.     private static LoadBalancer _instance;

  48.     private List<string> _servers = new List<string>();

  49.     private Random _random = new Random();

  50.  

  51.     // Lock synchronization object

  52.     private static object syncLock = new object();

  53.  

  54.     // Constructor (protected)

  55.     protected LoadBalancer()

  56.     {

  57.       // List of available servers

  58.       _servers.Add(“ServerI”);

  59.       _servers.Add(“ServerII”);

  60.       _servers.Add(“ServerIII”);

  61.       _servers.Add(“ServerIV”);

  62.       _servers.Add(“ServerV”);

  63.     }

  64.  

  65.     public static LoadBalancer GetLoadBalancer()

  66.     {

  67.       // Support multithreaded applications through

  68.       // ‘Double checked locking’ pattern which (once

  69.       // the instance exists) avoids locking each

  70.       // time the method is invoked

  71.       if (_instance == null)

  72.       {

  73.         lock (syncLock)

  74.         {

  75.           if (_instance == null)

  76.           {

  77.             _instance = new LoadBalancer();

  78.           }

  79.         }

  80.       }

  81.  

  82.       return _instance;

  83.     }

  84.  

  85.     // Simple, but effective random load balancer

  86.     public string Server

  87.     {

  88.       get

  89.       {

  90.         int r = _random.Next(_servers.Count);

  91.         return _servers[r].ToString();

  92.       }

  93.     }

  94.   }

  95. }

  96.  

 

Output

Same instance

ServerIII
ServerII
ServerI
ServerII
ServerI
ServerIII
ServerI
ServerIII
ServerIV
ServerII
ServerII
ServerIII
ServerIV
ServerII
ServerIV


 

.NET Optimized code in C#

 

The .NET optimized code demonstrates the same code as above but uses more modern, built-in .NET features.

Here an elegant .NET specific solution is offered. The Singleton pattern simply uses a private constructor and a static readonlyinstance variable that is lazily initialized. Thread safety is guaranteed by the compiler.

  1. using System;

  2. using System.Collections.Generic;

  3.  

  4. namespace DoFactory.GangOfFour.Singleton.NETOptimized

  5. {

  6.   /// <summary>

  7.   /// MainApp startup class for .NET optimized

  8.   /// Singleton Design Pattern.

  9.   /// </summary>

  10.   class MainApp

  11.   {

  12.     /// <summary>

  13.     /// Entry point into console application.

  14.     /// </summary>

  15.     static void Main()

  16.     {

  17.       LoadBalancer b1 = LoadBalancer.GetLoadBalancer();

  18.       LoadBalancer b2 = LoadBalancer.GetLoadBalancer();

  19.       LoadBalancer b3 = LoadBalancer.GetLoadBalancer();

  20.       LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

  21.  

  22.       // Confirm these are the same instance

  23.       if (b1 == b2 && b2 == b3 && b3 == b4)

  24.       {

  25.         Console.WriteLine(“Same instance\n”);

  26.       }

  27.  

  28.       // Next, load balance 15 requests for a server

  29.       LoadBalancer balancer = LoadBalancer.GetLoadBalancer();

  30.       for (int i = 0; i < 15; i++)

  31.       {

  32.         string serverName = balancer.NextServer.Name;

  33.         Console.WriteLine(“Dispatch request to: “ + serverName);

  34.       }

  35.  

  36.       // Wait for user

  37.       Console.ReadKey();

  38.     }

  39.   }

  40.  

  41.   /// <summary>

  42.   /// The ‘Singleton’ class

  43.   /// </summary>

  44.   sealed class LoadBalancer

  45.   {

  46.     // Static members are ‘eagerly initialized’, that is,

  47.     // immediately when class is loaded for the first time.

  48.     // .NET guarantees thread safety for static initialization

  49.     private static readonly LoadBalancer _instance =

  50.       new LoadBalancer();

  51.  

  52.     // Type-safe generic list of servers

  53.     private List<Server> _servers;

  54.     private Random _random = new Random();

  55.  

  56.     // Note: constructor is ‘private’

  57.     private LoadBalancer()

  58.     {

  59.       // Load list of available servers

  60.       _servers = new List<Server>

  61.         {

  62.          new Server{ Name = “ServerI”, IP = “120.14.220.18” },

  63.          new Server{ Name = “ServerII”, IP = “120.14.220.19” },

  64.          new Server{ Name = “ServerIII”, IP = “120.14.220.20” },

  65.          new Server{ Name = “ServerIV”, IP = “120.14.220.21” },

  66.          new Server{ Name = “ServerV”, IP = “120.14.220.22” },

  67.         };

  68.     }

  69.  

  70.     public static LoadBalancer GetLoadBalancer()

  71.     {

  72.       return _instance;

  73.     }

  74.  

  75.     // Simple, but effective load balancer

  76.     public Server NextServer

  77.     {

  78.       get

  79.       {

  80.         int r = _random.Next(_servers.Count);

  81.         return _servers[r];

  82.       }

  83.     }

  84.   }

  85.  

  86.   /// <summary>

  87.   /// Represents a server machine

  88.   /// </summary>

  89.   class Server

  90.   {

  91.     // Gets or sets server name

  92.     public string Name { get; set; }

  93.  

  94.     // Gets or sets server IP address

  95.     public string IP { get; set; }

  96.   }

  97. }

  98.  

 

Output

Same instance

ServerIV
ServerIV
ServerIII
ServerV
ServerII
ServerV
ServerII
ServerII
ServerI
ServerIV
ServerIV
ServerII
ServerI
ServerV
ServerIV

Credits:
http://www.dotnet-tricks.com/Tutorial/designpatterns/L2KL080613-Singleton-Design-Pattern—C#.html
http://www.dofactory.com/net/singleton-design-pattern

For More Design Patterns:
http://www.c-sharpcorner.com/UploadFile/sathvik/DesignPatterns11012005085547AM/DesignPatterns.aspx

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s