Design Patterns : Singleton
A Singleton, in software engineering, is a design pattern that is used when you only want/need to allow one instance of a class. This is specifically useful when the class instantiation of the said class is resource expensive (e.g. database connection, graphics driver, network resource and file streams…).
Below is a UML describing the implementation details of a Singleton.
Here is an example of a Thread-safe Singleton implemented in C#. In this example, we are trying to simulate a DbConnection object. The DbConnection object has a private constructor that blocks users of this class from ‘new-ing’ this object. Instead, the DbConnection object has a property called Instance that allows users creates a copy of DbConnection.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatternsWorkbook.SingletonPattern { public class Program { static void Main(string[] args) { // DbConnection object gets created on first call var connection1 = DbConnection.Instance; connection1.ConnectionTimeout = 100; // Create another instance to show that our Singleton is working var connection2 = DbConnection.Instance; //Compare both bobjects and see if they are equal if (connection1 == connection2) Console.WriteLine("connection1 and connection2 are the same instance\n"); //We've only set the ConnectionTime property on connection1. Let's check if it propagate to connection2 Console.WriteLine("Both should have the same connection timeout value."); Console.WriteLine(String.Format("connection1.ConnectionTimeout: {0}", connection1.ConnectionTimeout)); Console.WriteLine(String.Format("connection2.ConnectionTimeout: {0}", connection2.ConnectionTimeout)); Console.WriteLine("--------------\n"); //try to do a connection using connection1 Console.WriteLine("connection1.Connect() is called...."); connection1.Connect(); Console.WriteLine("--------------\n"); //try to do a connection using connection2 and see what happens Console.WriteLine("connection2.Connect() is called...."); connection2.Connect(); Console.WriteLine("--------------\n"); //try to disconnect using connection2 Console.WriteLine("connection2.Disconnect() is called...."); connection2.Disconnect(); Console.WriteLine("--------------\n"); //try to diconnect using connection1 and see what happens Console.WriteLine("connection1.Disconnect() is called...."); connection1.Disconnect(); Console.WriteLine("--------------\n"); Console.ReadLine(); } } /// <summary> /// Our Singleton class implementation /// </summary> public class DbConnection { // Make the constructor Private to prevent 'new' private DbConnection() {} // The instance read only property public static DbConnection Instance { get { return DbConnectionInstance.ConnectionInstance; } } /// <summary> /// A sample property /// </summary> public int ConnectionTimeout { get; set; } /// <summary> /// A sample property used to hold or Connection status /// </summary> public bool Connected { get; private set; } /// <summary> /// A sample method to simulate a connection /// </summary> public void Connect() { //check if the object is currently connected if (Connected) Console.WriteLine("Can't Connect. There is currently an active connection."); else { this.Connected = true; Console.WriteLine("You are now connected."); } } /// <summary> /// A sample method to simulate a disconnection /// </summary> public void Disconnect() { //check if the object is currently connected if (Connected) { this.Connected = false; Console.WriteLine("You are now disconnected!"); } else Console.WriteLine("There is no active connection to disconnect"); } // The nested class with the actual DbConnection object private class DbConnectionInstance { //our connection instance internal static readonly DbConnection ConnectionInstance = new DbConnection(); static DbConnectionInstance() {} } } } |
Running the above code will have this output:









