- Name Singleton
- Type Creational Pattern
Many times we need to restrict a class to only a single instance.Singleton pattern restricts the clients of the class from creating multiple instances of the class.There is a global access point ,such as a method,which returns the same object every time it is invoked.Singleton pattern is a creational pattern since it specifies how to create an object of a class.Here we will see the use and example of Singleton pattern in C#.
We can represent Singleton pattern with the following diagram
To implement singleton pattern follow the below steps
- Declare a private constructor: This ensures that consumers of the class can not create objects of the class.If we allow consumers to create new objects then we will not be able to restrict the class to a single instance.
- Declare a static field in the class.
- Declare a static method: This will return the static field declared in step 2.This method will create a new instance of the field if its doesn’t already exists.
The purpose of step 3 above is to ensure that there is a single interface for accessing the instance of singleton class.Singleton pattern doesn’t specify whether it should be a method or property.So we can implement this as a method or property.
Example of Singleton Pattern
In the following example we have declared a class Singleton which implements the Singleton pattern.This class defines a private constructor,a static field and a method CreateObject.CreateObject method created a new object of the class if it doesn’t exists.
There is an Id property which uniquely identifies each object.As this class can have only single instance so this property will never be incremented and should be always 1.
public class Singleton { private static Singleton _object; public int Id { get; set; } private Singleton() { Id = Id + 1; } public static Singleton CreateObject() { if (_object == null) { _object = new Singleton(); } return _object; } }
User create new object of the Singleton class by calling the CreateObject() method.We are calling the CreateObject method two times.We assign the references returned by the method calls to two different variables.
When we compare the two object references as:
singletonObject1==singletonObject2
they should be equal.
class Program { static void Main(string[] args) { //Following is not allowed and will give compilation error //int id = 1; //Singleton obj = new Singleton(id); Singleton singletonObject1 = Singleton.CreateObject(); Console.WriteLine("Object created.Object id is {0}", singletonObject1.Id); //try to create second object Singleton singletonObject2 = Singleton.CreateObject(); Console.WriteLine("Object created.Object id is {0}", singletonObject2.Id); if(singletonObject1==singletonObject2) { Console.WriteLine("Can not create second object.Singleton class can have only a single instance"); } else { Console.WriteLine("Successfully created second object"); } Console.ReadLine(); } }
As we can see from the output both the object references refers to the same object
We have used static method above to create instance of the singleton class.We could use static property instead of static method in our Singleton class:
public class Singleton { private static readonly Singleton _object= new Singleton(); public int Id { get; set; } private Singleton() { Id = Id + 1; } public static Singleton Instance { get { return _object; } } }
Use of Singleton pattern
Some of the scenarios where Singleton pattern could be useful are:
- A common use of Singleton pattern is implementing the logging class.Since logging class needs to be used multiple times in a application hence it is useful to implement it as a singleton.
- Often data fetched from a database needs to be cached.This cache class can be implemented as a singleton class since we need to have a single instance of the cached items.
- If we have an object that is resource intensive and so expensive to create ,it’s useful to implement it as a singleton.
Problem to avoid when implementing Singleton pattern
A problem can occur when there are singleton class is simultaneously accessed in a multi-threaded environment .In such cases the first call to singleton class creates an object,but it is not visible to the second call.So the second access to singleton class will try to again create an object of the singleton class.
A simple solution to concurrency is using the C# lock statement
lock (_object) { if (_object == null) { _object = new Singleton(); } return _object; }
A common example of Singleton Pattern in C# is implementing logger as a singleton class.Since logging is a cross cutting concern so it can implemented as a singleton class.
When developing a application design patterns should be chosen cautiously after weighing the pros and cons.Singleton design pattern is useful when the primary requirement is to limit the number of instances to a single instance.There could be different ways to implement the same design pattern.In the above example we have implemented singleton pattern in c# using a method but we could have used a property instead.
Leave a Reply