The Singleton pattern, probably the most hated pattern on the internet. But for the sake of being complete I feel obligated in implementing it once. <sarcasm>And never use it again</sarcasm>. Although this pattern has its use cases in some scenario’s. Caching could be one of them. Mind the usage of ‘could’ in the previous sentence. It could be a use case but as always: it depends.
Ensure a class only has one instance, and provide a global point of access to it.
I think this is a pretty well known pattern, a full explanation can be found on its Wikipedia page. For ASP.Net programmers that really don’t know what I’m talking about. You know the System.Web.HttpContext.Current property? Unfortunately, that’s a Singleton.
Let’s get our hands dirty. We’re going to implement our girlfriend as a singleton, because we are all good guys there is only one true girlfriend in our lives. So that will be our singleton. Let’s start with the implementation of our singleton Girlfriend class:
1: public class Girlfriend
3: private static readonly Girlfriend _instance = new Girlfriend();
5: private Girlfriend()
10: public static Girlfriend Instance
14: return _instance;
So this class is pretty straightforward. Our class has a readonly static class member that is instantiated when declared. And there is a property which returns the instantiated member. The constructor is private, so we can only create a new instance of the class within the class itself. This way we ensure that no instance of the Girlfriend class is created outside our class.
Our implementation does not lazy instantiate our singleton. There are other implementations which do lazy instantiation but then you have to take multithreading into account. If you’re interested in that implementation, this page gives a nice explanation about the different implementations of the Singleton pattern in C#.
The first test we write is to check if we always get the same instance from our Instance property. We check it by using the GetHashCode function, like this:
1: [Subject("Getting the girlfriend")]
2: public class When_getting_the_girlfriend
4: Because of = () =>
5: _hashCode = Girlfriend.Instance.GetHashCode();
7: It should_always_return_the_same_girlfriend = () =>
9: var hashCode = Girlfriend.Instance.GetHashCode();
13: private static int _hashCode;
Not that difficult, we call the Instance method 2 times and compare the hash codes of both instances. In fact, this confirms that our singleton works. But to be complete, let’s implement another scenario.
The next scenario, a common problem for everyone. Our house is dirty, we haven’t been cleaning for weeks and now it needs cleaning. Because our girlfriend is the best in the world she always volunteers to clean the house. Forgive me the sexism. So we have the following test case:
1: [Subject("Getting the person that cleans the dirty house")]
2: public class When_getting_the_person_that_cleans_the_dirty_house
4: Establish context = () =>
5: _dirtyHouse = new DirtyHouse();
7: Because of = () =>
9: _girlFriend = Girlfriend.Instance;
10: _personThatCleans = _dirtyHouse.CleaningPerson;
13: It should_return_the_same_person_as_our_girlfriend = () =>
16: private static DirtyHouse _dirtyHouse;
17: private static Girlfriend _girlFriend;
18: private static Girlfriend _personThatCleans;
There is the DirtyHouse class which exposes the person that is cleaning it via the CleaningPerson property. A separate variable is instantiated with the Girlfriend instance so we can compare the hash codes of the cleaning person and the girlfriend instance to ensure that both are the same instance. This test is actually obsolete because we are actually testing the Girlfriend class again instead of the DirtyHouse. But that’s outside the scope of this blog post.
This is the implementation of the DirtyHouse class:
1: public class DirtyHouse
3: public Girlfriend CleaningPerson
7: return Girlfriend.Instance;
No rocket science there. So this concludes the implementation of the Singleton pattern. As mentioned there are different ways to implement the pattern. A definite improvement would be to create an interface for our Girlfriend class so we can mock or stub it when testing other classes that use the Singleton. For example the test for the DirtyHouse class should actually mock the Girlfriend class via its interface so we can only test the logic in the DirtyHouse class and not if the Girlfriend is a singleton. But again that is outside the scope of this blog post.
Want to read more about the Singleton pattern? Check out these links:
- C# Singleton, Static Class on dotnetperls.com
- C# Tutorial – Singleton Pattern on switchonthecode.com
- Implementing Singleton in C# on msdn
- C# Singleton Pattern Code Snippet by Peter Bahaa
- Singletons in C#, Static Constructor vs Static Initialization by Mattia Baldingers
- C# Singleton Pattern Example by Matt Williamson
- C#: System.Lazy<T> and the Singleton Design Pattern by James Michael Hare
- Singleton Design Pattern by Nilesh Gule