Saturday, 22 September 2012

The Singleton Pattern in .NET - If you can avoid it

NOTE: This pattern is now considered by many (included the creators) an anti pattern and it is presented only for completeness! Read why.

The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it.

A Singleton is a class that manages a single instance of itself and prevent any other class from creating a new instance on its own. The only way to get the instance is passing through the Singleton class itself. 

Singletons are frequently used to provide a global access point for some service.

Let's see an example of Singleton that implement a trivial logging service.


and an example of usage:

OK but... what are the advantages?

As we said in the definition of the pattern, the main advantages are:
  • Making sure that there is a single instance of the service. This is accomplished making the constructor private and the class sealed.
  • Providing a global point of access to that instance.

Mmm but I can solve the same problem writing the following code, right?

It is true!

However, there are still some advantages in using the Singleton approach:
  • You don't have to put the static keyword everywhere
  • You can use singletons as parameters or objects
  • You can implement singleton with interfaces
  • You can write tests even if this is not simple
Anyway, singletons have more problems than benefits and these days many developers tend to avoid it if they can.

The biggest problem is the fact that you can use singletons where you want (they are like global variables) and dependencies are hidden inside the client objects. This means that the interface of the client objects don't reveals all the dependencies and this make testing very hard. In addition, in order to be able to write the tests you have to create a mechanism to replace singletons with mocks (a static Initialize method for example) that in some way violates the definition of singleton itself.

These days there are better ways to solve this problem and they usually involve other patterns like Service Locator and Dependency Injection. I will describe these patterns in later posts.

2 comments:

  1. You are doing a great job with your posts about design patterns!

    For alternative implementations of the Singleton pattern I would suggest checking this Jon Skeet's article:

    http://csharpindepth.com/Articles/General/Singleton.aspx

    ReplyDelete
    Replies
    1. Thank you very much and thanks for sharing. Very interesting article!

      I didn't mention laziness and thread safety just because I didn't want to put too much emphasis on the pattern that it should be avoided if possible.

      Delete

What you think about this post? I really appreciate your constructive feedback (positive and negative) and I am looking forward to start a discussion with you on this topic.