views:

1259

answers:

11

When should you NOT use a singleton class although it might be very tempting to do so? It would be very nice if we had a list of most common instances of 'singletonitis' that we should take care to avoid.

+2  A: 

I know many have answered with "when you have more than one", etc.

Since the original poster wanted a list of cases when you shouldn't use Singletons (rather than the top reason), I'll chime in with:

Whenever you're using it because you're not allowed to use a global!

The number of times I've had a junior engineer who has used a Singleton because they knew that I didn't accept globals in code-reviews. They often seem shocked when I point out that all they did was replace a global with a Singleton pattern and they still just have a global!

Ray Hayes
+7  A: 

Do not use a singleton for something that might evolve into a multipliable resource.

This probably sounds silly, but if you declare something a singleton you're making a very strong statement that it is absolutely unique. You're building code around it, more and more. And when you then find out after thousands of lines of code that it is not a singleton at all, you have a huge amount of work in front of you because all the other objects expect "the" sacred object of class WizBang to be a singleton.

Typical example: "There is only one database connection this application has, thus it is a singleton." - Bad idea. You may want to have several connections in the future. Better create a pool of database connections and populate it with just one instance. Acts like a Singleton, but all other code will have growable code for accessing the pool.

EDIT: I understand that theoretically you can extend a singleton into several objects. Yet there is no real life cycle (like pooling/unpooling) which means there is no real ownership of objects that have been handed out, i.e. the now multi-singleton would have to be stateless to be used simultaneously by different methods and threads.

Thorsten79
+6  A: 

Well singletons for the most part are just making things static anyway. So you're either in effect making data global, and we all know global variables are bad or you're writing static methods and that's not very OO now is it?

Here is a more detailed rant on why singletons are bad, by Steve Yegge. Basically you shouldn't use singletons in almost all cases, you can't really know that it's never going to be needed in more than one place.

William
I haven't read that Stevey post in a while. Thanks!
Mark Roddy
+2  A: 

I'm guilty of a big one a few years back (thankfully I've learned my lession since then).

What happened is that I came on board a desktop app project that had converted to .Net from VB6, and was a real mess. Things like 40-page (printed) functions and no real class structure. I built a class to encapsulate access to the database. Not a real data tier (yet), just a base class that a real data tier could use. Somewhere I got the bright idea to make this class a singleton. It worked okay for a year or so, and then we needed to build a web interface for the app as well. The singleton ended up being a huge bottleneck for the database, since all web users had to share the same connection. Again... lesson learned.

Looking back, it probably actually was the right choice for a short while, since it forced the other developers to be more disciplined about using it and made them aware of scoping issues not previously a problem in the VB6 world. But I should have changed it back after a few weeks before we had too much built up around it.

Joel Coehoorn
Word: Lession Pronunciation: \'les-zhən\Usage: NounDefinition: Something learned from being cut or torn open.
md5sum
A: 

One of the things that tend to make it a nightmare is if it contains modifiable global state. I worked on a project where there were Singletons used all over the place for things that should have been solved in a completely different way (pass in strategies etc.) The "de-singletonification" was in some cases a major rewrite of parts of the system. I would argue that in the bigger part of the cases when people use a Singleton, it's just wrong b/c it looks nice in the first place, but turns into a problem especially in testing.

André
A: 

Sometimes, you assume there will only be one of a thing, then you turn out to be wrong.

Example, a database class. You assume you will only ever connect to your app's database.

// Its our database! We'll never need another
class Database
{
};

But wait! Your boss says, hook up to some other guys database. Say you want to add phpbb to the website and would like to poke its database to integrate some of its functionality. Should we make a new singleton or another instance of database? Most people agree that a new instance of the same class is preferred, there is no code duplication.

You'd rather have

Database ourDb;
Database otherDb;

than copy-past Database and make:

// Copy-pasted from our home-grown database.
class OtherGuysDatabase
{
};

The slippery slope here is that you might stop thinking about making new instance of classes and instead begin thinking its ok to have one type per every instance.

Doug T.
A: 

When you have multiple applications running in the same JVM.

A singleton is a singleton across the entire JVM, not just a single application. Even if multiple threads or applications seems to be creating a new singleton object, they're all using the same one if they run in the same JVM.

David
Well that is only half of the truth, see here: http://java.sun.com/developer/technicalArticles/Programming/singletons/
André
+1  A: 

Singletons are virtually always a bad idea and generally useless/redundant since they are just a very limited simplification of a decent pattern.

Look up how Dependency Injection works. It solves the same problems, but in a much more useful way--in fact, you find it applies to many more parts of your design.

Although you can find DI libraries out there, you can also roll a basic one yourself, it's pretty easy.

Bill K
+1  A: 

I try to have only one singleton - an inversion of control / service locator object.

IService service = IoC.GetImplementationOf<IService>();
JC
+1  A: 

Here is a rant by my friend Alex Miller... It does not exactly enumerate "when you should NOT use a singleton" but it is a comprehensive, excellent post and argues that one should only use a singleton in rare instances, if at all.

Michael Easter
A: 

In the case of a connection (for instance), it makes sense that you wouldn't want to make the connection itself a singleton, you might need four connections, or you may need to destroy and recreate the connection a number of times.

But why wouldn't you access all of your connections through a single interface (i.e. connection manager)?

Aaron H.