Do We Still Need the Singleton Pattern?

Posted by & filed under , , .

iStock_000013471133XSmallIf you have been working in software engineering for a while chances are you have often come across (even if you didn’t know it!) design patterns. If you haven’t, as I said, chances are you just don’t realise you have used them — so I strongly suggest the “Gang of Four” book as a starting point. Personal note here: I believe some of those are outdated and/or hardly needed nowadays — which is why I’m writing this post! But nevertheless, as per my initial comment, the GoF book is a good point to start.

One of these design patterns is the Singleton pattern — for some unknown (to me!) reason, the world (and by the world here I mean the Java world) is still raving about this bloody thing. Even more so, it keeps popping up in every other interview I am involved in (on either side of the interviewing process) — and every single time I see this happening I get more annoyed, because I frankly think it’s useless! I’m going to try to explain my point of view here.

Let’s look first at what a singleton is — quoting from Wikipedia, which seems to summarize the GoF description of this pattern:

“In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object.”

OK, so this tells us that implementing a singleton means ensuring that one particular class gets only one instantiation. It might seem a paradox in itself doing this doesn’t it? When anyone starts diving into any OOP language, the idea pushed forward a lot is that this facilitates code reuse a lot more: you encapsulate functionality in your class and users of your library/class either extend or instantiate this class wherever and whenever needed — thus suggesting that when dealing with code reuse, one ought to expect a lot of instances of the class implemented!

Wikipedia, again, provides an insight into how this pattern might help and why the need for it:

“This is useful when exactly one object is needed to coordinate actions across the system.”

OK, so this tells us that the reason for having only one instance is because this particular instance will hold references to everything else in my system and will help coordinate actions amongst them. For instance think of a cache object — all classes using this cache will have to share the same instance. However, to me this doesn’t read that we must restrict absolutely without a shadow of a doubt the class instantiation to one single instance: instead, to me it suggests that in a lot of situation we ought to share one single instance of a class across multiple components.

This, believe it or not, makes a coder life much easier — because here’s what you end up writing for a singleton code in Java:

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

OK, so this is relatively simple: we have a static member, initialize it on class load and then return it on getInstance() calls. We of course make the constructor private such that no one else apart from the class itself has access to it.

You’d think everyone would be happy with this but no 🙂 Apparently we want to make our lives complicated and add the problem of the object only needed to be created when it’s needed (why else would we create it???) and so we need to apply some lazy initialization. Right… so we go and re-write the code like this:

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

Now you think this would be enough but no! We’re now hearing complains about the fact that the getInstance() function is synchronized — this means only one thread at a time can enter the function which of course creates a bottleneck: while it’s fine all threads but one to be blocked when we create the instance, once created we want our threads no longer to be blocked when returning the already-created instance. So then we re-write our code again and stepped into double-checked locking issues now:

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

Since Java 6, we have enum‘s so now we can use an enum which is guaranteed by the JVM to be a single instance so can use this “hack” to save us time and code.

Then of course there’s always questions like what if the constructor is really heavy and throws exceptions? Or what if it doesn’t throw exceptions but it takes a long time to run — maybe it needs to read stuff from the network or database? How do we go about ensuring this gets initialized way before other components in the system so they don’t have to wait on this? And the (silly) list of questions goes on.

And throughout all of these we seem to forget the important aspect I’ve outlined earlier: we do not need to limit in most cases the number of instances of the class, but instead we need to ensure the same instance is shared amongst all components!

In which case, all I have to say is this: use the Spring framework! (Or in fact any other dependency injection framework.) Simply define one bean in your configuration XML and pass it to all the other beans! This way we don’t have to worry about limiting the number of instances via horrible pieces of code as per above (or some enum-based hacks) — our beans stay normal, without any synchronization code regarding the creation and retrieving the bean. Also, the framework will wait for each bean to initialize, so we don’t have to worry about “pausing” our components till this particular one is ready. And last but not least, we get one single instance in the Spring context — shared amongst all components!

Conclusion: I have made myself the mistake of asking candidates in interviews about the Singleton pattern, but I have realised recently that I actually haven’t used that in ages. Maybe, there might be edge cases when you need to implement a Singleton pattern as per above yourself, but I bet those are rare and only in specialized cases — personally, I haven’t had a need for this in over a year now. Every time I needed “something like a singleton” I found out that the Spring framework helps by sharing one instance across the whole context. So I can save time and headache (and weird production bugs!) this way.

As such, I’ll ask again: as coders, do we really still need the singleton pattern?

Leave a Reply

Your email address will not be published.