8

Possible Duplicate:
When is Singleton appropriate?

I've seen many explanations why is Singleton is evil. But is there really no such a case when Singleton is the only beautiful solution?

eigenein
  • 181
  • 3
  • 4
    [When is Singleton appropriate?](http://programmers.stackexchange.com/questions/252/when-is-singleton-appropriate) – Problematic Sep 12 '11 at 16:05

4 Answers4

3

want to hear a common myth?

"Singletons are a way to limit the number of instances of a certain class to one."

Yeah, right.

If that's how most people used singletons, the only thing I would have to say is "Well, why not just create ONE and stop there?"

But that's not the issue. The real problem here is that people use singletons to introduce global state to object-oriented programs, or just to shove in another (anti) pattern.

If you want to have a single instance of a certain class, that's perfectly fine. But why make it accessible from anywhere in your code? That's called opacity, my friend, and that's what you should watch out of.

Instead of using singletons, read up some more on dependency-injection and chain of construction (factories, etc). Depend on services (objects) you need. Don't try finding them by yourself (from the object's point of view) or access them globally.

Yam Marcovic
  • 9,270
  • 2
  • 27
  • 29
  • Well sometimes it can be very complex to make one object in the widget hierarchy accessible to another object somewhere else in the hierarchy. So you can just have a singleton class Registry where the interesting objects register themselves. Then any time you need an object you grab it (as a smart pointer) through the registry. I would be interested to know whether this is considered dangerous and why. – Giorgio Sep 12 '11 at 17:48
  • You're talking about GUI. There are better ways to program GUI as well. Use a mediator and event handlers. Use binding. Singleton Registry is not the only (and most certainly not the best) solution. P.S. I don't support GUI testing anyhow. – Yam Marcovic Sep 12 '11 at 17:56
  • Ok, let's suppose I use a mediator object. Won't there be just one mediator object through which the communication goes? – Giorgio Sep 12 '11 at 18:01
  • this is not better than a rant because it just parrots the anti-singleton argument with no demonstrations of alternative solutions. –  Sep 12 '11 at 18:08
  • 1
    I'm sorry. I thought dependency injection would have automatically popped into your head. Well, since it didn't... Then yes, dependency injection. I.E. instead of calling the global getInstance(), simply depend on the proper class and have your caller instantiate you properly, whether through a factory or not. – Yam Marcovic Sep 12 '11 at 20:03
  • @giorgio Previous to my current project I had a singleton EventHub to manage communications between the GUI and control modules. Now I inject the EventHub into all GUI and control objects; so much for that singleton! – jhocking Sep 13 '11 at 18:34
  • @jhocking: I understand, I also use this pattern: inject a common mediator object, e.g. when I create my GUI objects. I am trying to see the benefits of this solution wrt having a registry from which all objects get the mediator. This seems rather equivalent to me at the moment (the complexity is just moved somewhere else but not reduced) but I have to think about it. Maybe I will really have to stop using registries (?) – Giorgio Sep 13 '11 at 19:03
  • I'm not sure why all your various objects need to know about the registry. The only object that needs to know about the registry is the one instantiating the other objects (eg. your Main class). So you still have a central registry, but there's no need to make the registry a Singleton. – jhocking Sep 13 '11 at 19:32
1

It depends on what you call a Singleton.

edit> The link from Problematic in the question's comments might help to understand what I mean here : When is Singleton appropriate?

If the construction and destruction of the unique instance don't have to be explicit, then it's EVIL.

If not, then there are some specific cases where it's clearly a good solution. The main one I'm using is when the unique instance represent the state of a "system" that is "global", like a hardware api.

That said, if you're in this case, you could replace your singleton by free functions... if your language allows it. If not then I guess it's a reasonable choice.

Just keep in mind : global access means that if there is a problem with your singleton object, you might have propagated it everywhere it is used. That's why if you can remove the global accessibility, it would be far better.

In a more general way, when you start thinking that a singleton might be necessary, think twice or more. It can always be replaced. There is just a tradeof that might be (or not) too expensive for you. Now it don't mean you don't have to use it at all ever in your life. It might be worth sometimes. But it's rare. So, as a rule of thumb, just don't use it. Rules are made to be understood then to be broken when you understand when it's a good idea.

Klaim
  • 14,832
  • 3
  • 49
  • 62
  • 1
    I don't agree. Even if the state is de facto entirely global, there's usually no reason on earth to make that state accessible from anywhere in your program. Singletons aren't evil by themselves. Opacity is. And singletons create opacity. Not to mention you won't be able to test it, because you're always going to be stuck with the actual hardware state at the moment of the test. – Yam Marcovic Sep 12 '11 at 16:41
  • You just can't test those hardware API anyway, so that's not a problem of Singleton. Again I don't think Singleton is good but it depends on what you mean by "Singleton". Global access is problematic yes, but sometimes global state is exactly what you need to reflect. As suggested, if you can use free functions instead (like in C or C++) it's far better but if you can't you're just stuck with passing objects all over some systems. That might be good but sometimes it is just expensive. Sometimes it's necessary evil. But that should be very rare. – Klaim Sep 12 '11 at 16:53
  • I think the link in comments explain better what I mean. – Klaim Sep 12 '11 at 16:54
  • I didn't explain myself well enough. I don't mean testing *the* hardware API, I mean testing *your* logic that depends on it. And that you *should* test, or at least be able to. And just because the "state is global" for the process, doesn't mean it should logically be so as well. If you think about it, any bit in your process' memory space is global in that way. But that doesn't mean we want to access it from anywhere. Quite the opposite. Languages have developed to allow programmers more and more encapsulation possibilities. Exposed global state is most often harmful. – Yam Marcovic Sep 12 '11 at 17:05
  • If your logic depends on a unique state provided to you as functions, you have two choices : provide your logic as functions or bounded in a global access class (that can or not be singleton). What's the difference? In C++ both can have state. In other languages, it depends. There is no one right truth and even goto can be useful. -- I mean that I disagree. :) – Klaim Sep 12 '11 at 20:16
1

Yes.

When trying to shoehorn an app into some tiny, very memory and/or performance constrained, micro-controller. One can even turn a singleton into a global var/struct/array, which the compiler can optimize into far fewer bytes of machine code.

For super high volume consumer items, beauty is often saving a few pennies or cubic mm. Generality (portability, reusability, maintainability, etc.) has costs. No need to pay if you aren't going to use the benefits that go with those costs.

hotpaw2
  • 7,938
  • 4
  • 21
  • 47
  • Do you have anything to back up that "far fewer bytes" part? If a fellow programmer told me he's using singletons "to save on bytes" I'd quite honestly laugh in his face. The picture I have in mind is "Yeah I'm programming this little micro-processor, so I'm using C++ and singletons." Am I missing something? – Yam Marcovic Sep 13 '11 at 17:58
  • You can disassemble the output of your preferred toolchain and count the bytes of machine code for different design patterns. The results will vary by language and compiler. – hotpaw2 Sep 13 '11 at 18:29
  • The question is - is it enough to make me care about it, in the environments I'm deploying to? I hardly believe any object-oriented language will be a right choice for an environment that strictly prefers the least amount of instructions on top of all other things. Either way, using singletons isn't going to save up on cubic MM, because we're talking about general-purpose processors here, not customized logic arrays. – Yam Marcovic Sep 13 '11 at 18:49
0

I have never seen nor heard of any case which justifies limiting an object to just one instance.

Even in hardware, you can never guarantee what can happen in the next few years- for example, in 1990 or 1995 you might have said that a graphics driver might reasonably use one. But then, you get SLi invented. Whoops. The same occurred with printers. You can't justify the use of a Singleton just because it doesn't make sense - it has to be actively system-destroying. Such instances do not exist.

DeadMG
  • 36,794
  • 8
  • 70
  • 139
  • 3
    then you have never had to deal with hardware drivers or anything that is resource constrained to a single entry point. –  Sep 12 '11 at 18:11
  • 3
    I believe the case of hardware is the example included in the GoF book. There are many times when having two pieces of hardware defies logic, and the Singleton enforces that on your application. – Thomas Owens Sep 12 '11 at 18:16
  • Jarrod, that example does not say why the same instance should be accessible from anywhere in the code, and not only in places that explicitly declare their dependency upon it. – Yam Marcovic Sep 12 '11 at 20:05
  • @Jarrod: And then tomorrow, somebody invents SLi, or networked printers, or a dozen other cases where it used to be guaranteed that you only ever needed one, and you're back to needing more than one instance anyway. – DeadMG Sep 13 '11 at 02:31