On Singletons

March 12, 2007 - 4 minute read -
ood mock-objects

The Singleton Pattern is one of the most widely used patterns from the Gang of Four (GoF) Desgin Patterns Book. One the reasons that it's so widely used, I think, is because it's also very easy to understand. The basic idea is that you control the creation of an object so that it will only ever have one instance. This is achieved by having a private constructor and a static instance that is accessed through a static method on the Class.

Singleton Example:

public class FirstSingleton {
    private static final FirstSingleton instance = new FirstSingleton();
    public static FirstSingleton instance() {
        return instance;
    }
    private FirstSingleton() {
    }
}

Reasons to Avoid the Singleton Pattern

Practical Limitations

There are some practical limitations of the Singleton pattern though. With modern VM based languages like Java there can be multiple classloaders in a given application. A Singleton then is no longer a Singleton as there will be an instance-per-classloader. So if you can't enforce an actual single instance why use the Singleton Pattern? You might answer that the classloader case is a rare one and that in a "normal" application your not going to run into that. And you would be right. But I still think that you should avoid the Singleton

Multiple Concerns

Fundamentally a Class in Object Oriented Programming should have one and only one responsibility. The Single Responsibility Principle often leads to good design and the benefits of a highly-cohesive system such as being easily understood and being easier to change and maintain over time.

The Singleton, by its very definition, has multiple responsibilities. The primary responsibility defined in the pattern is controlling constructions of Objects of this Class. Of course from an application point of view, this is pretty weak. What you really want from a class is a useful service. So if you have a Singleton Data Access class which is more important? The Singularity of the instance or the ability to get at data in your data store? I really hope you picked the latter.

There are a number of ways that you can control access to the construction of a class that do not rely on the Singleton pattern. A Factory or a Container for example can be used to get at an instance in such a way that the calling code doesn't care about the implementation of the construction of the class. Whether a new instance is created or a single instance returned should be immaterial to the user of that instance. This also does a good job of dealing with our Single Responsibility concern raised earlier. Now the inforcement of a single instance is handled by another class whose sole responsibility is that singleton enforcement.

Testability

One consideration that must be made when you are designing software is: How are you going to test the code? If no consideration is given, then often the code will be very difficult to test and quality will suffer.

The example of a Singleton above is relatively simple. But what happens if you introduce a dependency to your Singleton? Now you have a tight-coupling between two classes. If the dependent class does something like access the database or call a web service or itself has a bunch of dependencies then all of a sudden the code becomes very hard to test.

public class SecondSingleton {
    private static final SecondSingleton instance = new SecondSingleton();
    private SomeDependency myDependency;
    public static SecondSingleton instance() {
        return instance;
    }
    private SecondSingleton() {
        myDependency = new SomeDependency();
    }
}

I've written previously about Mock Objects for testing. Mock Objects allow you to create dummy implementations of dependencies to make testing a Class much easier. In the Singleton example here, you can see that there would be no way to inject a Mock instance into the SecondSingleton class.

Factories or Containers to Enforce Single Instances

One of the best ways to access dependencies in a class is through Constructor based Dependency Injection. This can be done through a container like Spring or Pico Container.

You can of course do this yourself as well. If you are using a Factory for object creation, then the singleton enforcement and the dependency injection can happen in the same class (whose sole responsibility is to manage the construction of objects).

public class NotSingleton {
    private SomeDependency myDependency;
    private NotSingleton(SomeDependency depends) {
        myDependency = depends;
    }
}
public class Factory {
  private NotSingleton notsingleInstance
    = new NotSingleton(
      (SomeDependency) lookupType(SomeDependency.class));
  public NotSingleton getNotSingleton() {
    return notsingleInstance;
  }
  /**
   * Get an instance for a given Interface
   * @param interface The interface for which you want the instance
   */
  public Object lookupType(Class clazz) {
    // ...
  }
}

With this structure you can now independently test all of your classes without worrying about the interactions of dependent objects. You also have not structured the code in such a way that having multiple instances should cause any problems, so your code won't break if the classloader case ever comes up.