Skip to main content

Using Singletons Safely

The singleton is probably the best known of the GoF Design Patterns, it’s also the most controversial. I try avoid using singletons in my code when I can but since the singleton is a very simple but powerful pattern I sometimes sin against the decoupling gods and use one or two of them. Lots of stuff has been written about creating singletons. In this post I want to show you how properly use a singleton and contain most of the damage singletons do.

This post was inspired by a Twitter discussion I had with @LaTtEX who blogs here

First lets talk about all the reasons not to use a singleton. The objection I hear most against singletons is thread safety. The problem here is that if two threads access the the singleton simultaneously when the singleton isn’t created yet the singleton might accidentally create two instances of itself. The naive implementation has this problem and even some solutions that have been suggested like double checked locking aren’t completely thread safe. This isn’t why I dislike singletons though. I think the biggest problem with singletons is coupling.

Singletons are accessed through static methods. Calling a static method couples your code to the implementation of that method so every call to the Instance property or method of a singleton makes your code harder to test and harder to maintain. A call to a singleton by definition has side effects. Usually these are very large, singletons are usually used for resource intensive objects that you only want to create once. You don’t want to be coupled to code with severe side effects.

My strategy for defusing singletons is actually quite simple. Reduce the number of MySingleton.Instance calls. Lets say we have a singleton for logging that we want to use in a repository class, something like this.

   1: public class Repository
   2: {
   3:     public IEnumerable<MyClass> ReadObjects()
   4:     {
   5:         Logger.Instance.LogMessage("ReadObjects started");
   6:  
   7:         // ..code..
   8:  
   9:         Logger.Instance.LogMessage("ReadObjects finished");
  10:     }
  11:  
  12:     public void StoreObject(MyClass anObject)
  13:     {
  14:         Logger.Instance.LogMessage(String.Format("StoreObject {0} started", anObject.Id));
  15:         
  16:         // ..code..
  17:         
  18:         Logger.Instance.LogMessage("StoreObject finished");
  19:     }
  20: }

 

Coupling-wise things can’t get much worse than this. Every time something is logged Logger.Instance gets called making our Repository object depend not only on the Logger class but also on it’s implementation as a singleton. This is not something we want our repository to be aware of. We can easilly make this a bit better by creating the instance once and reusing it.

 


   1: public class Repository
   2: {
   3:     private Logger logger = Logger.Instance;
   4:  
   5:     public IEnumerable<MyClass> ReadObjects()
   6:     {
   7:         logger.LogMessage("ReadObjects started");
   8:  
   9:         // ..etc..

 

The code is a little bit better because I’m not repeating my mistake over and over but I’m still not satisfied. Let’s see how I can improve this even further.

 


   1: public class Repository
   2: { 
   3:     private Logger logger;
   4:  
   5:     public class Repository(Logger logger)
   6:     {
   7:         this.logger = logger;
   8:     }
   9:  
  10:     public IEnumerable<MyClass> ReadObjects()   
  11:     {   
  12:         logger.LogMessage("ReadObjects started");
  13:  
  14:         // ..etc..
  15:  

Here I used the constructor to inject the logger instance into my class. This is a simple concept but it has a big impact on the flexibility of your code. Your classes aren’t aware of how objects need to be instantiated anymore. This makes code more testable and maintainable. You can inject a class that derives from Logger, as long as it works the same as its base class this will just work. Usually I even hide classes that provide a common service like logging or caching behind an interface to decouple usage of instances even more from their implementation.


If you really paid attention you probably noticed that by having the Logger injected into the Repository in its constructor you have made the instantiation of the singleton a bit less lazy. You might never even call ReadObjects and never need the Logger. If you really need instantiation to be that lazy you could inject the Logger as a parameter into the ReadObjects method, I found that usually injecting in the constructor is fine.


You might say that by pushing the call to Instance out of my repository into the code that creates the repository I have only moved the problem somewhere else, and you would be right. But this problem can actually be solved by moving it. As long as you move it in the right direction. I’ve put the code that creates the repository and the code that gets an instance of the Logger together. If you do this for more of your code you’ll end up with creation and usage of your classes nicely separated with all the code that’s responsible for wiring up your application nicely centralized.

Comments

Popular posts from this blog

Using xUnit.Net with .Net 4.0

I’ve been using xUnit.Net for a while now. It’s just a tiny bit cleaner and slightly less abrasive than other .Net unit testing frameworks. Leaving out unnecessary stuff like [TestFixture] and shortening Assert.AreEqual to the equally clear but shorter Assert.Equal don’t seem like big improvements but when you type them several times a day tiny improvements start to add up. I also like the use of the [Fact] attribute instead of [Test]. It shifts the focus from testing to defining behavior. So how do we get all this goodness working with the Visual Studio 2010 beta?

Square One available on the Android market

This is just a short post to let you know that a first version of the Android app I’ve been working on for the last couple of weeks is available on the Android market. The app is called Square One and it’s a simple bassline synthesizer. It’s free so try it out and let me know what you think of it, but be prepared it’s still an early version. I hope to add more features in the next few months and maybe build something that can be used to create real music.The lower part of the screen contains the sequencer controls that can be used to program your own bass lines. On the left is a four by four grid of buttons where you can select a step in the sequence. On the right you can select the note to be played on that step. When you’re done you can press Start and the sequence starts playing. The knobs on the top can be used to control a couple of parameters from the synthesizer engine that creates the sound. You can control the cutoff frequency and resonance of the low-pass filter, attack and …

Building Android projects with Jenkins, Ant and Mercurial

I have recently set up a Jenkins build server for my Android projects hosted on Bitbucket. It’s not difficult but there are a couple pitfalls and the information on how to do this isn’t available from one single place so I decided to document the process and put up the information over here. Maybe other people will benefit from having a step-by-step guide too.