Is Singleton Root of All Evil?

Yes.

Despite all its criticism, singletons still exists today, perhaps because insecure programmers feel the illusion of doing the “right” thing, since they are after all using a design pattern. For those who think, “What experts do, must be right”, I will leave a famous quote by Christopher Hitchens-

Picture all experts as if they were mammals. … Seek out argument and disputation for their own sake.

The popularity of the word ‘singleton’ probably comes from set theory, where it is a set with exactly one element. Similar to its mathematical counterpart, a singleton pattern in software engineering ensures exactly one instance of a class for each running application. This is how you would write a singleton class in Java:

public class Singleton {
    private static final Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
         if(instance == null)
               instance = new Singleton();
         return instance;
    }
}

Since the instance can be shared by many threads, you probably want to make it thread safe. You can find the thread-safe implementation and other optimized implementations here, but for the purpose of this post, this code will do. Since the constructor is private, this class cannot be instantiated anywhere other than ‘getInstance()’ method, where it can be instantiated just once. Hence singleton!

Let me give you a quick example where singleton is preferable over static class. When I say static class, I mean static class that has global static variables. Static class that does not have any static global variables are perfectly good designs, like a ‘Math’ class with a method ‘Math.sum(…)’. Consider a ‘Config’ class that reads the config info from a file and save them to its global static variables. If the config variables are accessed before calling the ‘read()’ method, then they will be ‘null’. So, as a programmer you have to remember to call the ‘read()’ method at the start of the program. Although it is not much of a hassle, but a singleton class can ensure you call the ‘read()’ method, since you can just call it in the constructor. Both singleton class and static class with global static variables are bad, but if you must choose, here is a rule to find the lesser of two evils.

If the class may or may not be initialized depending on input, is costly to create, or requires calling another method before using its variables then use Singleton; otherwise use static class.

Now let’s discuss why singletons are a bad programming practice.

  • Decent programmers know that global variables in a class are bad and should always be avoided if possible. A singleton class gives global access of its instance variable to the entire code base. The programmer needs to be extra careful, since changing it in one part of the program can have disastrous consequence to some other parts.
  • A singleton class cannot be mocked. That means you cannot create a dummy instance of the singleton class, which makes unit testing a nightmare. For each test, you basically have to save the state of the singleton, set the singleton with test required initialization, perform test, and load the state back. Otherwise, you will not be able to confidently run multiple test at the same time.
  • Singleton will make you a bad programmer. Since singletons are easy way out, you will keep using it even in classes where dependency injection is clearly a better choice. Specially when you are fighting a deadline, you will use singletons where they can be easily avoided. Before you know it, you will have a big pile of unmaintainable code that you will use most of your time refactoring.

So, how do you fight this evil? Simple answer is dependency injection. Pass the instance of the class as a parameter to other classes that need it. Here are the steps [ref: Alex Miller].

  • Create an interface and a default implementation of your singleton
  • Construct a single instance of your default implementation at the top level of your system.
  • Pass the single instance into each component that needs it (dependency injection)

It solves the problem with unit testing since you can now mock the object (i.e., implement the interface as a mock class or create a subclass of the actual implementation, etc.). However, the global state still cannot be avoided. But, that is not the right way to do things anyway. By that I mean, you should only consider making a singleton class when the information flows just one way (like a logging class or a config class where you just write or just read). If multiple class need to read and write the same resources, may be you should merge those classes together or find another way around (How To Write Unmaintainable Code is a must read if you want to be a quality programmer. Also search for how to avoid code smells to learn some tricks for reducing dependencies). If none works, at least do the dependencies in the top level, i.e., you can call a function of a lower level class by its instance and you can let the top level know about any changes by an event.

Finally, singleton is a good choice to use for a logging class, because the information flow is one way (a necessary condition) and logging does not affect the code logic in any way (the sufficient condition). Also, logging can be used in almost every class  of the project, making dependency injection very painful!

 

Note 1: There are workarounds for singleton implementation for languages that does not support private constructors. For example, in AS3 one can write an internal dummy class inside the same file as the singleton class but outside of its package scope. Therefore, the dummy class can only be access by the singleton class. So, if the singleton takes the dummy class as an argument of its constructor, then it cannot be instantiated by any other class. The code will look like this:

/**
* Web Link: http://blog.pixelbreaker.com/actionscript-3-0/as30-better-singletons
**/
package
{
  public class Singleton
  {
	public static var instance:Singleton;
	public static function getInstance():Singleton
	{
	    if( instance == null ) 
                instance = new Singleton( new SingletonEnforcer() );
	    return instance;
	}
	public function Singleton( pvt:SingletonEnforcer )
	{
	    // init class
	}
  }
}
internal class SingletonEnforcer{}

Tagged: , , , , ,

One thought on “Is Singleton Root of All Evil?

  1. […] any way. To learn why singletons should be avoided in most cases, you can check out my other post here. This is also where we create the chain. To process a logging request we must start with the lowest […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: