The Singleton pattern is a creational design pattern in which a class is guaranteed to only ever have exactly one instance, with that instance being globally accessible.
What this means is that the pattern forces a particular object to not have an accessible constructor, and that any access performed on the object is performed upon the same instance of that object.
As you may have heard, Singleton is one of the most maligned design patterns (for reasons we will discuss below).
NOTE: This post is part of a series demonstrating software design patterns using C# and .NET. The patterns are taken from the book Design Patterns by the Gang of Four. Check out the other posts in the series!
The Rundown
- Type: Creational
- Useful? 2/5 (Rarely, but worth knowing so you can hunt them down)
- Good For: Creating an object of which there can only ever be one.
- Example Code: On GitHub
The Participants
- The Singleton is a class which defines exactly one instance of itself, and that instance is globally accessible.
A Delicious Example
The theme I've been using for the Daily Pattern series so far is "food", but food items are not a good way to model Singleton: there's not ever going to be a piece of food that everybody will access a single instance of (because that would be gross).
Instead, let's visit our local diner and think about that little bell that sits on the counter.
In movies, one of the best ways to identify that the characters are in a greasy diner is by having an overweight chef with a dirty apron tap a bell and shout "Order Up!".
The thing about that bell is that there's probably only one; the sound is used to notify the servers that the next order is at the window and needs to be taken to the tables.
If there's only ever one bell, we can model it as a Singleton.
/// <summary>
/// Singleton
/// </summary>
public sealed class TheBell
{
private static TheBell bellConnection;
private static object syncRoot = new Object();
private TheBell() { } //A Singleton needs a private constructor
/// <summary>
/// We implement this method to ensure thread safety for our singleton.
/// </summary>
public static TheBell Instance
{
get
{
lock(syncRoot)
{
if(bellConnection == null)
{
bellConnection = new TheBell();
}
}
return bellConnection;
}
}
public void Ring()
{
Console.WriteLine("Ding! Order up!");
}
}
Notice that the TheBell
class has a private constructor. This is to ensure that it can never be instantiated, and can only be accessed through the Instance
property.
Further, note the syncRoot
object. This a simple object that allows our Singleton to be thread-safe; since there's only ever one, we must ensure that any thread which wants to access it has an exclusive lock on it.
This Pattern Has Problems
Singleton is probably the most maligned of the original design patterns, and for good reason.
For one thing, Singletons are not global variables, though the latter is often mistaken for the former. A Singleton is a class unto itself, and global variables are just properties.
Further, many people argue that Singletons violate common guiding principles such as the Single Responsibility Principle. By its very nature, you cannot pass a Singleton to other classes, and this is often a code smell.
Mostly, though, Singletons are maligned because they are so often misused. It's entirely too easy, to paraphrase Jamie Zawinski, to see a problem, think "I know, I'll use a Singleton," and end up with two problems. Be careful that what you're using the Singleton for actually requires that pattern, and even then be on the lookout for a better, more appropriate manner by which you can solve your current problem.
Will I Ever Use This Pattern?
Not on purpose.
Kidding, kidding. Sort of.
Thing is, Singletons are (fittingly) good for one and only one purpose yet are easily understood and quick to implement, which makes them a favorite of people afflicted with golden hammer syndrome. It's all too common to find Singletons in use where global variables should be used instead.
Use the Singleton design pattern sparingly and only for its intended purpose (a single, globally accessible instance of an object) with full knowledge of this pattern's limits, and you'll find that it, like all the other design patterns, has its own set of valid uses.
Summary
Singletons are objects of which there can only ever be exactly one instance. They're not global variables and many people think they violate common principles of good software development, but they do have their uses and so should be used sparingly.
DING! Order Up and Happy Coding!