Yesterday, I came across a question from my colleague, “What is the difference between static class and singleton class?” So I thought of writing a blog about singleton class (or singleton design pattern) and analyze the differences with static class.
Many people start describing Single design pattern saying, “We need to create a static class”; which is absolutely wrong. Since static class cannot have any instances and Singleton pattern advocates having a single instance of class. I have covered the differences between Singleton class and Static class in the last section of this blog.
Singleton Design Pattern
Definition
Singleton is derived from mathematics singleton set, (or unit set), i.e., a set with exactly one element.
Singleton pattern is a design pattern that restricts the instantiation of a class to single object, i.e., only one instance of the class is possible. It ensures that a class has only one instance and provides a global point of access to it.
UML Class Diagram
In the UML above, the 1 on top right (not a standard UML practice) signifies that only one instance of the object should be created.
-
The class Singleton contains a private member or field named instance of type Singleton itself. This field has to be declared static as this field will be used by the static read-only Property (having Get method only) named Instance.
-
The constructor of the class is declared as private.
-
Singleton class can have instance methods as well.
Note: Instead of static property (Instance), we can use static method; say GetInstance().
Why static property?
Like all static members of a class, static property is initialized only once and is members of the Class instead of Instances. Hence, making the property static provides a global point of access, because once the instance is created the Instance property will always be pointing to the same instance, and static members are never garbage collected.
Why private constructor?
The constructor is declared private to restrict creation of instances from outside the class. Only the methods and properties of the class can create instances using new keyword.
Implementation
Classic Singleton
public class Singleton
{
//Static field of type Singleton to hold the
//reference of first instance.
private static Singleton instance = null;
//Private constructor to restrict instance
//creation from outside the class
private Singleton() { }
//Public static property of type Singleton
//to provide global point of access
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
//Public method of the Singleton class
public void Method()
{
Console.WriteLine("Method called");
}
}
OR
public class Singleton
{
//Static field of type Singleton to hold the
//reference of first instance.
private static Singleton instance = null;
//Private constructor to restrict instance
//creation from outside the class
private Singleton() { }
//Public static method of type Singleton
//to provide global point of access
public static Singleton GetInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
//Public method of the Singleton class
public void Method()
{
Console.WriteLine("Method called");
}
}
Advantages of Classic Singleton
-
Since the instance is created inside the Instance property or GetInstance() method, the class can provide additional functionality (e.g., instantiating a subclass, initializing other static members etc)
-
Lazy instantiation, i.e., the instance is not created until it is asked for by other class. This avoids creating Singleton instances during the application load, thereby removing overhead when application starts.
Disadvantages
Only one disadvantage is that it is not safe for multithreaded applications, as multiple threads can execute the Instance property or GetInstance() method and execute
if (instance == null)
at the same time and choose to create new instance, thereby creating more than one instances. To overcome this disadvantage we can use Static Initialization Singleton implementation.
Static Initialization Singleton
//Class is declared sealed to prevent deriving from this class
//as subclasses can add instances
public sealed class Singleton
{
//Static field of type Singleton to hold the reference of
//first instance. The field is readonly to ensure that it
//is assigned only during static initialization
private static readonly Singleton instance = new Singleton();
//Private constructor to restrict instance
//creation from outside the class
private Singleton() { }
//Public static property of type Singleton
//to provide global point of access
public static Singleton Instance
{
get
{
return instance;
}
}
//Public method of the Singleton class
public void Method()
{
Console.WriteLine("Method called");
}
}
Advantages of Static Initialization Singleton
-
Derived classes cannot add instances.
-
The instance field is read-only. This ensures that it is assigned only during the static initialization.
-
This is also a form of Lazy initialization i.e., the instance is not created until it is asked for by other class.
Note: The above implementation can be modified for Eager initialization by making the field instance public and removing the property Instance. In this case the initialization happens even before any of the class or instance members is accessed.
Disadvantages
This implementation provides less control over the mechanics of the instantiation, i.e., the class cannot provide additional functionality (e.g., instantiating a subclass, initializing other static members etc).
Multithreaded Singleton
There are certain rare scenarios when static initialization is not suitable for multithreaded environment; viz., when application must delay the instantiation or perform other tasks before the instantiations. In such cases .NET framework cannot ensure thread safety and the developer needs to handle the thread safety issues.
The following implementation provides a thread safe Singleton class that allows only single thread to enter the critical area when no instance of Singleton has yet been created and create the first instance.
//Class is declared sealed to prevent deriving from this class
//as subclasses can add instances
public sealed class Singleton
{
//Static field of type Singleton to hold the reference of
//first instance. The field is volatile to ensure that
//assignment to the variable is complete before it can be used.
private static volatile Singleton instance;
//Static field of type object to be locked upon before entering
//the critical section (where instance is created)
private static object synchronizer = new Object();
//Private constructor to restrict instance
//creation from outside the class
private Singleton() { }
//Public static property of type Singleton
//to provide global point of access
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (synchronizer)
{//Critical section starts [Equivalent to Monitor.Enter(synchronizer)]
if (instance == null)
instance = new Singleton();
}//Critical section ends [Equivalent to Monitor.Exit(synchronizer)]
}
return instance;
}
}
//Public method of the Singleton class
public void Method()
{
Console.WriteLine("Method called");
}
}
Advantages of Multithreaded Singleton
Disadvantages
None. But used in rare scenarios, when critical section has other critical tasks to be performed before creating the singleton instance.
Uses of Singleton
-
The Abstract Factory, and Builder patterns can use Singleton class in their implementation as only one instance of abstract factory, or builder is generally required.
-
Facade Objects are often Singletons because only one Facade object is required.
-
A typical use of singleton pattern is designing load-balancer; as only one instance of load balancer is required.
Limitation of Singleton
Singleton ensures that only one instance of the object is created; though it can not ensure the destruction of the instance.
Difference between Singleton and Static Class
-
A static class must have all the members declared as static, whereas a singleton class needs only the global point of access as static and other members can be instance members.
-
A static class cannot implement interfaces, whereas singleton class can implement interfaces.
-
A static class must derive from object class only and cannot derive from other base classes whereas singleton class can derive from other base classes. Hence a static class can only provide compile time polymorphism (overloading) whereas singleton class can provide both compile time (overloading) and runtime polymorphism (overriding)
-
A static class cannot have subclasses as static classes are sealed by definition; whereas singleton class can have subclasses (provided the singleton class is not declared as sealed).
-
A singleton class can point to a subclass of itself whereas a static class cannot have a subclass.
-
A static class cannot be serialized where as singleton class can be serialized. This is necessary in cases when developer needs to save the instance state to disk or send remotely.
-
A static class provides better performance as the compiler emits non-virtual call to the members. This prevents the runtime check that ensures the current object pointer is not null.
-
A static class is always initialized eagerly whereas singleton class can be initialized lazily (See Advantages of Classic Singleton).
When to use static class
Static class should be used when you have to provide collection of related functions that needs to be accessed directly without instantiating like Math class in C# (Util class for projects etc.)
Feel free to check out my other posts on OOPS:
http://beyondrelational.com/modules/2/blogs/716/Posts/16010/oops-a-detailed-understanding-of-concepts.aspx
http://beyondrelational.com/modules/2/blogs/716/Posts/16026/oops-classes-and-their-relations.aspx
http://beyondrelational.com/modules/2/blogs/716/Posts/16114/oops-basic-overview-of-class.aspx