Software Reality
Programming with
a dose of satire.

Site Map Search


Agile Development
 
Extreme Programming
 
Code Generation


Articles
Lifecycle
Design
Programming
Soapbox
Reviews
Cthulhu

Check out our ageing Reviews Section


Use Case Driven
Use Case Driven Object Modeling with UML: Theory and Practice
Get from use cases to working, maintainable source code. Examples use Spring Framework, JUnit and Enterprise Architect

Agile UML
Agile Development with ICONIX Process
A practical subset of agile development techniques, illustrated by example

Get Controversial!
Extreme Programming Refactored
Extreme Programming with a dose of satire
Available now:



ICONIX/Sparx Public Classes to Come to London

ICONIX is planning a series of open- enrollment public classes entitled Hands-On Enterprise Architect for Power Users in collaboration with Sparx Systems.




Design

Perils of the Singleton

By Matt Stephens
October 17, 2004

I realize this has been discussed in the past, but I thought I'd add my vote to the "Singletons are evil" debate. Not that Singletons really are evil, of course: not unless they're specifically programmed to do despicable things. And Singletons do have their uses. But the "evil", if that's the right word, is that they frequently are misused horribly.

A Singleton is a very simple design pattern which allows you to restrict a class to a single instance in an application. This is done by making the constructor private, and giving access to only a single instance via a static accessor method. Here's an example Singleton in Java:

public class BeanController {
    private BeanController() {}

    public static synchronized BeanController getInstance() {
        if (instance == null) {
            instance = new BeanController();
        }
        return instance;
    }

    private static BeanController instance = null;
}

As you can see, it's a very simple concept. So simple, in fact, that Singletons tend to be used almost everywhere. They're incredibly useful, but - and here's the problem - they can also lead to bad, inflexible designs.

Singletons are used inappropriately because people confuse having to make something single-instance with only happening to need a single instance at the time - two very different things.

There are several problems with the Singleton design pattern, the worst ones being:

Singletons make unit testing difficult. In particular, singletons tend to assume a lifetime longer than a single unit test; so they're difficult to reset ready for the next test.
They can't be reused. If you find that a different module can make use of your controller class, you might be tempted to give it a separate instance to play around with. But you can't because it's a Singleton. But when you decide to change it, that leads to the next problem...
They're difficult to extend (assuming you want the subclass to also be a separate instance). Because the instance is got via a static method, it can't easily be overridden with a more specialized singleton. This can be worked around, but not particularly elegantly.
Any code which uses the class will naturally assume the class can only have a single instance, even if it doesn't need to. Changing cardinality could lead to all sorts of nasty bugs and breakage.

As you can see, Singletons restrict your design. By their very nature (and intent) they lock you in to a single instance of a class. While this might be okay at the time, it restricts future refactoring of the design. Once a class has become a Singleton and other classes have begun using it, it can be difficult to make it a non-Singleton (multiton?), as the rest of the design will have evolved around the concept.

Change leads to breakage: but changing cardinality can lead to carnage. You'll find that much of your code makes subtle assumptions based on the fact that certain classes have only one instance. In short, overuse of Singletons leads to sloppy design.

If a class isn't restricted in this way, you can do all sorts of things with it: create unit tests more easily, create multiple versions, pass different versions around, clone them and so forth. You might not need to do any of these things at the time when you create the Singleton, but later you might need to - and discover that you can't, because the Singleton has locked you in. In short, avoiding Singletons wherever you can leads to a malleable, flexible design.

A common (mis)use of Singletons is to provide a static lookup - an easy way of finding a controller class from anywhere in the application: in other words, the OO equivalent of a global variable. While this can simplify your code nicely when used sparingly, a more appropriate solution would be to at least add a context parameter to the static lookup: so you get back a different instance depending on the context object that you pass in. Even if your application only ever uses the one context, it makes it that much easier to extend with new instances later. It's still not a complete solution, but gets you halfway to a more malleable design.

Singletons are problematic because they're so easy to create. This sounds counterintuitive, but it's an easy trap to fall into: they're a sloppy answer to a sometimes tricky problem - how to associate multiple unrelated classes with a single controller, without cluttering your interfaces by having to pass the controller class around everywhere.

The simple answer is to do some class design up-front using paper and pen (or CASE tool or whatever), and work out in advance where all the dependencies are, and work out the least intrusive way of giving them access to the controller instance - always remembering that what you are aiming for is a self contained controller class which can be created any number of times without causing errors.

It's worth emphasizing the point I made earlier: Much of the time, a Singleton class doesn't actually need to be restricted to a single instance: it only seems like it because (at the moment at least) the application doesn't need more than one instance of it. These are two very different things.

Singletons are not evil, although a genuine Singleton - a class which absolutely must be restricted to a single instance - is a rare thing. When you find such a class (e.g. a factory which churns out IDs), don't hesitate to make it a Singleton: it's the right thing to do. But in all other cases, be wary of creating Singletons for the sake of it, as they naturally restrict your design.

 

Elsewhere on the Web:

Singletons are Evil (Google search - a lot has already been written on the subject!)

 

<< Back to Design

<< Back to Software Reality

 

All trademarks and copyrights on this page are owned by their respective owners.
Stories and articles are owned by the original author.
All the rest Copyright 1998 onwards Matt Stephens. ALL RIGHTS RESERVED.