On the good use of the singleton design pattern

The most common argument against using singletons can be summarised in this quote:

When you mention singletons it’s common to get a dismissive reply, something in the lines of “singletons are only glorified global variables”.

This is not unlike how I have treated suggestions to use the singleton design pattern as a solution to a problem. However, there are good uses of the pattern too, and in this post I outline one of them.

The singleton design pattern isn’t so much about only having one instance of a class as it is about providing control over the instantiation of a class.

This slight shift in focus is important, because if you put the emphasis on having one instance, you’re in the global variable mess, and you don’t want to be there.

The quote above is true if you litter your code with code like this:

Foo.getInstance().doSomething();

// ...

Foo.getInstance().doSomethingElse();

This is exactly the same as having a global variable. It can make your application harder to debug, it will definitely make it harder to understand your code and your application will be more fragile and harder to change.

However, looking at the instantiation control aspect of singleton we can see that you don’t have to use a singleton in way of the example above. Just because there is global access point to the singleton doesn’t mean you have to use it everywhere. Instead, use getInstance() once, and then pass the object around as you would any other object.

foo = Foo.getInstance();

bar.setFoo(foo); baz.setFoo(foo); // ...

The objects bar and baz in the example above don’t know that Foo is a singleton, and neither do they need to know. They know only that they get passed an object which they can use and no more.

The benefit of this is that if you later decide that Foo doesn’t need to be a singleton anymore – perhaps you want to have exactly two instances, or a pool of instances, the only code you need to change is the part where you get the instance, the rest of your application just doesn’t care.

11 Responses to “On the good use of the singleton design pattern”

  1. Richard Lord Says:

    I’m not clear why your example is an improvement over the standard

    foo = new Foo(); bar.setFoo(foo); baz.setFoo(foo); // …

    By using the Singleton pattern you have

    1. Restricted the class to a single instance.
    2. Provided global access to the instance (whether you use it or not).
    3. Forced an uncommon technique for instantiating the class.

    If you’re purpose is only to restrict the class to a single instance, why not simply define Foo as

    class Foo{ private static var instantiated:Boolean = false;

    public function Foo()
    {
        if( instantiated )
        {
            throw new Error("Only one instance of Foo is permitted");
        }
        instantiated = true;
        // ...
    }
    

    }

  2. Theo Says:

    You are right in all your points, but you have misunderstood the context. What I try to say is that there are many bad ways to use the singleton design pattern, but if you, for any reason, use the pattern (or the factory pattern) that doesn’t mean that you have to treat the singleton instance as if it was different from any other object.

    And in comment to your suggestion for limiting the number of instances: well yes, it works, but why throw an exception? Why not use the singleton pattern, which solves exactly this problem?

  3. Richard Lord Says:

    The reason for not using the Singleton pattern is because it requires an unusual method of instantiation (and hence explaination to other members of your team, possibly with explaination of the Singleton pattern too) and it provides global access to the instance (which you may not abuse, but others in your team might).

    It seems to me that if you’re going to pass the single instance around and not use the global access then using the Singleton pattern just adds unnecessary complexity.

  4. Theo Says:

    Firstly, the singleton pattern doesn’t use an unusual method of instantiation because instantiation is still done behind the scenes with new. Secondly, having method which returns an instance is not unusual, almost every method that has a return type other than void does this. I don’t see how you can call this method of instantiation unusual.

    What I think you’re against is that the instantiation is hidden, but this is also true for most of the common object oriented programming idioms and patterns that deal with the creation of objects. Take for example the factory method, abstract factory and other creational patterns.

    Abstraction often leads to the details being hidden. Just think of interfaces, every time you program against interfaces instead of concrete classes you have no control (in the sense I think you would like) over the instantiation, and you don’t even know the actual type of the object you’re using (only the interface type).

    To answer your other issue, that if I’m going to pass the singleton instance around just like any other object the method of instantiation is meaningless, I would like to say: yeah, sure, if I’m not going to allow global access to the instance I can use a few other techniques for ensuring that there is only one instance, but why? I have a perfectly good pattern, tried and tested, why not use it? Because it has an “unusual method of instantiation”? How is throwing an exception in the constructor of a class not something unusual? What if I change my mind later and want to have a pool of instances instead of a single one? Perhaps return a subtype instead? Using the singleton pattern those changes will not require much, but other techniques (like the exception throwing) would definitely do that.

    There is a lengthy discussion about the singleton pattern here: http://c2.com/cgi-bin/wiki?SingletonPattern which I think is a good read.

  5. Richard Lord Says:

    My previous post could have been simpler – the reason for not using the singleton pattern is because it adds complexity for no gain. Your application is creating a single instance of the class and then passing it around. That’s simple, straightforward, and easy to understand. The moment you make the class a singleton you add complexity. And for what gain? To limit the class to a single instance? That’s already controlled by the application only creating one instance. To allow global access to the instance? You’re not using that. So why?

    Re: Unusual

    By making the class constructor private, you force developers to use Foo.getInstance() to access an instance of the class. That a call to new happens behind the scenes is not in question. That developers can’t directly use new and have to call the static method instead is unusual. Unusual enough that Actionscript 3 doesn’t even allow private constructors.

    Re: Exception in constructor

    It is not usual for a constructor, or any other bit of code, to throw an exception when it encounters an error. In fact, in Actionscript 2 this is the best way to ensure only a single instance is created since the private qualifier is only tested at compile-time, not run-time, so making the constructor private (as in the singleton pattern) is not foolproof.

    Re: Hidden instantiation.

    I’m not against hidden instantiation. I am against unnecessary complexity.

    Re: “Just think of interfaces, every time you program against interfaces instead of concrete classes you have no control (in the sense I think you would like) over the instantiation, and you don’t even know the actual type of the object you’re using (only the interface type).”

    Using interfaces has nothing to do with instantiation, but anyway… Yes I do know the type. An interface is a type. I know I’m dealing with an object of that type.

    Re: “What if I change my mind later and want to have a pool of instances instead of a single one? Perhaps return a subtype instead? Using the singleton pattern those changes will not require much, but other techniques (like the exception throwing) would definitely do that.”

    To allow more than one instance later: Using the singleton pattern, you have to strip out the singleton code and change all calls to getInstance into calls to new. i.e. you change code in various places through your program. Using the exception, you simply remove the code that throws the exception. i.e. you make a simple change in the class itself.

    To use a subtype: Using the singleton pattern, strip the singleton code from the class and place it in the subtype instead. Using the exception, just use the subtype (the base class will throw the exception if you create more than one) – no changes required.

    To use a pool of objects: You should probably use a factory, which requires the changes to the class indicated above to allow more than one instance.

    Seems to me the exception is easier to change later, not harder.

    Re: Singleton

    The singleton pattern is to “Ensure a class only has one instance and provide a global point of access to it” (GoF). If you don’t want the global point of access, I don’t think this is the best pattern to use.

    I get the impression that you like the singleton pattern because it is both a class and a factory for managing instances of that class. But this is the problem with it. By bundling both features into a single class you limit reuse of the class to situations where you also want the factory. It’s better to create a simple class, and then create a factory to manage instantiation as required. Unless, that is, the class must be restricted to a single instance or it will break. But even then I generally prefer throwing an exception when attempting to create a second instance. The real benefit of the singleton is the double whammy of single instance and global access, but that’s not often a requirement.

    Re: Links

    You might also consider these resources on singletons:

    http://www-128.ibm.com/developerworks/webservices/library/co-single.html http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx http://www.bigroom.co.uk/blog/better-without-singletons/

    The last is my own.

  6. Theo Says:

    I really think we have both misunderstood each other.

    I mistook you for someone who didn’t understand the point of the singleton pattern, but reading your last comment (and the post you link to) it is obvious that you do, and that your oppinion about it is quite close to mine.

    However, I think you also have misunderstood my view on the matter. The point of the original post was to show that singleton instances are not special, and that just because you have a singleton that doesn’t mean you have to use the global access feature.

    What I think you have misunderstood is that I’m not especially for the singleton pattern, I actually quite reluctant to use it because it usually causes more problems than it solves. I still think there are legitimate uses for the “ensure a class only has one instance” part of the definition though, and by not treating that instance as special I see no problem with the pattern as such (although I agree with you on the point that the pattern gives a class multiple responsibilities and a factory is often preferable).

  7. Richard Lord Says:

    Then all is well. If only it was this easy to undo all the other misunderstandings in the world.

  8. Theo Says:

    I second that.

  9. nwebb Says:

    These comments and your respective posts made for a thoroughly engaging read guys.

    I see the reason to avoid Singletons where possible, and also have a better way to deal with them when I have to (for example, working on a project which uses Cairngorm as the architectural framework).

  10. Theo Says:

    Not that I know much about the Cairngorm architecture (I stopped reading after I realised how much it promotes global variables), but in a comment on Jeff Houser’s blog I outlined a solution to how to avoid some of the mess:

    http://www.jeffryhouser.com/index.cfm/2008/3/27/Learning-Cairngorm-Part-6-Dealing-with-the-Singleton

  11. nwebb.co.uk » Blog Archive » Using Cairngorm & Thoughts On Handling Those Pesky Singletons Says:

    [...] are some links which I found to be useful: http://www.bigroom.co.uk/blog/better-without-singletons http://blog.iconara.net/2007/05/08/on-the-good-use-of-the-singleton-design-pattern/ [...]

Leave a Reply