Open main menu

CDOT Wiki β

Singleton

Introduction

Singleton pattern Ensure a class only has one instance, and provide a global point of access to it. This is useful when exactly one object is needed to coordinate actions across the system.

Implementation

  • Singleton pattern is implemented by creating a class with a method that creates a new instance of the object if one does not exist.
  • If an instance already exists, it simply returns a reference to that object.
  • To make sure that the object cannot be instantiated any other way, the constructor is made either private or protected.

UML Diagram

 

Sample Code

Singleton pattern in C#:

// Singleton pattern -- Real World example  

using System;
using System.Collections;
using System.Threading;

namespace DoFactory.GangOfFour.Singleton.RealWorld
{
  
  // MainApp test application 

  class MainApp
  {
    static void Main()
    {
      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

      // Same instance? 
      if (b1 == b2 && b2 == b3 && b3 == b4)
      {
        Console.WriteLine("Same instance\n");
      }

      // All are the same instance -- use b1 arbitrarily 
      // Load balance 15 server requests 
      for (int i = 0; i < 15; i++)
      {
        Console.WriteLine(b1.Server);
      }

      // Wait for user 
      Console.Read();    
    }
  }

  // "Singleton" 

  class LoadBalancer
  {
    private static LoadBalancer instance;
    private ArrayList servers = new ArrayList();

    private Random random = new Random();

    // Lock synchronization object 
    private static object syncLock = new object();

    // Constructor (protected) 
    protected LoadBalancer() 
    {
      // List of available servers 
      servers.Add("ServerI");
      servers.Add("ServerII");
      servers.Add("ServerIII");
      servers.Add("ServerIV");
      servers.Add("ServerV");
    }

    public static LoadBalancer GetLoadBalancer()
    {
      // Support multithreaded applications through 
      // 'Double checked locking' pattern which (once 
      // the instance exists) avoids locking each 
      // time the method is invoked 
      if (instance == null)
      {
        lock (syncLock)
        {
          if (instance == null)
          {
            instance = new LoadBalancer();
          }
        }
      }

      return instance;
    }

    // Simple, but effective random load balancer 

    public string Server
    {
      get
      {
        int r = random.Next(servers.Count);
        return servers[r].ToString();
      }
    }
  }
} 

References