26

Possible Duplicate:
When is Singleton appropriate?

I am a new programmer (4 months into my first job) and have recently taken an interest in design patterns. One that I have used recently is the Singleton. However, looking at some comments on this thread. It has some bad feedback; can somebody explain why?

I have found it useful in some places, however I could probably have achieved the same without it using a static class.

1

7 Answers 7

27

It has the same problems as a global variable.

It gives you global accesses to mutable state.

Anything that uses the Singleton is now tightly coupled to it.

Try and avoid tight coupling. It makes the code hard to update. Hard to test.

If your choice is a Singleton or global variable. Than at least Singleton provides lazy initialization.

But usually it is best to avoid globally accessible mutable state and pass in all dependency to your code via parameters or in the constructor. This decouples your code from specific instances.

Note: Global access to constant state is not such a big deal.

Here is a good talk about the subject done by Google Engineers:
http://www.youtube.com/watch?v=-FRm3VPhseI

Singleton pattern looks like it is one of the easiest to implement (when you first see Design Patters). It is relatively easy to do but there are a couple of gotchas in its implementation (all of which are language specific). But the hardest part of learning about Singleton's is; learning when to use them (which should be rarely (most people would argue never, but I find it hard to convince my-self that I could never use a Singleton (thought the few times I have, most have been mistakes (but that is how we learn))).

3
  • 6
    You can still have lazy initialization with a "global" object using an accessor. Many people mistake "I only want one" with "only one should ever be allowed". There's no need to harm your not-a-singleton class' testability if you don't need to.
    – CB Bailey
    Jan 16, 2011 at 19:25
  • Normally I implement a "normal" class and subclass a singleton-version of it, because I can't predict if I need new instances in the futur or not
    – K..
    Oct 22, 2012 at 14:32
  • "Anything that uses the singleton is now tightly coupled to it" is just not true. It's only true "Most things that use the singleton do tight coupling" and so the bad part about it isn't the singleton, but how people use and abuse it. Just like with global vars. programmers.stackexchange.com/a/218322/4261
    – cregox
    Nov 13, 2013 at 15:30
13

The only time a singleton is useful, over a simple global variable, is when you require global access and it's an error to have more than one instance. Some people use singletons to represent log files, but it's not an error to have more than one instance of your log class (for example, you might want to log to a separate file for some particular purpose: if your log class was a singleton, that's now impossible).

Note it's not just a matter of requiring global access. It's global access and it's an error to have more than one instance.

Usually, if you need global access, a global variable will suffice (people don't like global variables, but singletons are certainly not a solution to over-use of global variables). An even better approach is often to use Aspect-oriented programming in place of singletons and global variables.

2
  • 3
    Preach it! I keep finding Singletons in my current codebase that were added by over-enthusiastic new-hires. So far I don't think I've seen one that actually needed to be a singleton. And I have removed one or two that needed NOT to be a Singleton. Jan 18, 2011 at 1:40
  • The keyword there is often. Well put, sir!
    – cregox
    Nov 13, 2013 at 16:52
5

You might find this helpful: https://stackoverflow.com/questions/2765060/stateless-singleton-vs-static-methods/2765251#2765251

To summarize:

  • the advantage of an actual singleton over a static class is, a singleton can implement interfaces
  • the point of a singleton is not to grant global access to a value, but to control instantiation of a type.

greetz
back2dos

3

Singletons make sense when they represent something which is by it's nature inherently one--normally something with a real-world existence, although it can also make sense when it represents a static resource of some kind.

2

One thing you have to be careful about with singletons is making sure they actually are singletons. For example, with Java if you don't take a few extra measures when creating your singleton, and you have many threads wanting access to it, you might end up having many instances of your "singleton".

Also, if you have an application that makes use of RMI, and you end up creating a "singleton" on the client and server, then do you still have a singleton?

I know these are just Java examples, but I am just making a few points. The problem most people cite is that some objects that seem like they should be singletons, really don't need to be one. For example, it might be nice to have a single instance of some object factory, but there's no need to force it. You could only explicitly create one, but having two around wouldn't break things.

2

Without examining that thread, I can tell you I've seen it used numerous times as just a thin wrapper around a global variable. It's akin to putting lipstick on a pig... Just because you've wrapped it in a design pattern, doesn't make it OK.

edit: Apparently I need to explain why globals are bad? You can read about globals here if you need an intro.

"Scribes frequently use Singletons in a misguided attempt to replace global variables. I have, for example, been on projects where the Singleton has been described as 'a well-known object' -- does that not sound like a global variable, my child?"

"Umm... no, not really," I drawled after a bit of consideration. I wrote on my whiteboard:

S &S::Instance() 
{   
    static S theInstance;   
    return theInstance; 
}

"I don't see a global variable here." "Ah, my child, but there is a global variable -- a global variable named S::Instance(). Consider this parable:

class T { /* whatever */ }; 
T globalT;

"What is the difference between globalT and theInstance? Both variables have static storage duration, do they not?"

Therefore, never create a Singleton whose sole purpose is to mask a global variable.

3
  • Aaah...I understand and yeah that would be pretty shitty. I've used it with fully encapsulated classes that I require only a single instance. I find by using the Singleton it's far easier to just use the instance reference rather than lots of new objects. Jan 16, 2011 at 18:30
  • 2
    -1 - This doesn't explain WHY it's bad. Just says "it's bad".
    – Sergio
    Jan 16, 2011 at 18:47
  • 1
    It is bad because it tightly couples your code to the singelton/global. Tight coupling makes the code hard to update and very difficult to test. it also adds hidden dependencies into the code that are not obvious from the use of the code. Jan 16, 2011 at 18:59
1

Putting lipstick on a pig. That's so interesting that i had to create a new answer:

So it means that, for logging...

  • You can't create sepatate singletons for each logging target, eg logError()->write, logWarning()->write, etc (???)
  • You can't select log type when getting singleton log(TYPE)->write (???)
  • You can't just create another instance of class, when needed (you can have same class using singleton for "global" logging and then yo can create an instance for something specific) (???)

So what is, in your opinion better than using singletons in this case?

  • Maybe passing log class instance to every function in every class object
  • Maybe just creating the log class on demand, and it'll mean that you'll have to open lock / close the file as many times as you have rows (very optimal:)
  • Static class... same problem. Performance will suck...
  • Global functions (nice mess)
  • Global objects (nice mess again)

Singletons are good design practice because you can always modify global object somewhere, or someone else can just overwrite it. Not possible with singleton pattern.

Bad feedback? From uneducated developers? :) Ok, let's say that if you abuse any pattern you'd find it sucks, so we should conclude that every design pattern sucks because it could be abused. And mySQL have bad press over mongoDB, too :) You know the word "press" it's the key. Press is just looking for sensations and journalists really don't know what they talk about.

Math functions, anyone? Math.max()... nice idea to not create an object each time you want to do some simple math op, right? :)

Static class - you use it when you don't need to preserve state or resources between function calls (eg. do math functions, each on is unrelated to previous and doesn't require system resources). For eg. logging you use singletons, because you'd want to keep FileSystem Object Handle to not open/close it over and over again.

8
  • 'Singletons are good design practice because you can always modify global object somewhere, or someone else can just overwrite it. Not possible with singleton pattern.' ?? Could you clarify the difference between 'singleton' and 'singleton pattern'?
    – Michael K
    Jan 16, 2011 at 20:19
  • Hm... singleton is a concept or something you can use and singleton pattern is how you'll make that concept work.
    – Slawek
    Jan 16, 2011 at 20:24
  • 3
    Singletons only fix small problems with global variables. Global variables encourage coupling which ideally we'd like to prevent. The technique of using singletons does nothing to help there. The complaint against singletons is basically that people convert a global variable into a singleton and think all is good. But really they've only fixed relatively minor issues that come from using globals. Jan 16, 2011 at 20:55
  • 2
    Regarding Math, that's not a singleton its a static class. There is no problem with static/global functions as long as those functions as long as they are stateless. Jan 16, 2011 at 21:00
  • 1
    You might also examine some large open source "C" based projects for a solid example of how to handle logging etc w/o a singleton pattern. Apache, for one. Even in an OOP system, if you litter your code with what is basically a global object, then you are tightly coupling your code (bad OOP) and making unit testing a nightmare.
    – red-dirt
    Jan 17, 2011 at 13:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.