Why are singletons bad?

Started by
90 comments, last by _moagstar_ 15 years, 1 month ago
Quote:Original post by davepermen
well, it's so hard to understand me.

what defines the difference of a singleton to a global is the singletonity, a.k.a. the single-instance-feature.

the question is, when, ever, is that feature in any form useful.

I am sorry from reading these boards for a while, it is just a slippery slope to start justifying or discrediting singletons and this is something which I will not do.

I will assume that your post about not being global was genuine error.

"You insulted me!" I did not say that in the private message Tom Sloper!
Advertisement
i ment that's not what a singleton is about. that's what any type of global is about. but for that, just use a global. what reason do you have to choose a singleton over a global. that (part of the) definition is what really matters here.

for anything that is not about "single instance of a class", a global works perfectly well with all it's features and problems.

that's what i mean with define it. that's it's "big thing". that's what makes it unique, what differentiates it from anything else. the globality is nothing special. and globality is relative anyways.

now the question is, where is the restriction to only one instance a feature-gain for your system. and my answer: never, except if it's outright dangerous to have more than one instance.


i'm very bad at english today... hope you get my point, even while i worded it all in a wrong way for anyone else except me :)
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

Original post by the_edd
Quote:Original post by TheMac
I am going through this in my head and I can't understand why for one, singletons are hard to test in your unit tests.


You might be able to unit test a singleton, but you cannot unit test anything that uses that singleton.


Not true, at work I replaced the way we do encryption with an encryption/decryption manager (singleton), changed the code in one class to one single call to the manager, and the unit test that was already in place continued to run with no problems.

In other words, I replaced some complex boilerplate code with the manager, and our tests still worked, so why are people saying its hard or impossible to test?

Quote:Original post by davepermen
Quote:Original post by Antheus
Ever tried unit testing a database application where you need to test DROP statement? In common design where database access is singleton or global hard-coded, accidentally running such test without changing the configuration will wipe the production system. So how do you test it automatically?

Much easier if systems are not coupled.


QFT.

not exactly a DROP statement, but in general. once it's a hot database, with money-data in, and all, and you have to test stuff around, have fun if you can't just switch the database easily. i first had, in all my apps, a singleton connection (just so damn easy in .net). i learned the quite hard way (no dataloss in the end in the database) that this isn't how it should go :)

singletons are just bad. everyone who doesn't understand this still has to learn a lot in clean, save, proper programming.

i do use globals sometimes. i do use global functions sometimes. but never singletons.

edit:

i have found quite some places where globals can be handy (in small scale apps, that is). i never found one point, where a singleton has any gain over a global. if i thought it may be that way, taking the global away and making it a locally pass-around object was always simpler to implement, less to think about, and then, 100% working and debuggable and testable.



You say I have a lot to learn because I use singletons sometimes, but then you just said you will use globals? How are singletons bad programming, but globals are not?
if your singleton doesn't contain a state you can unit test stuff using it with no problem. but at that point, you don't need a singleton, but just global methods.

but if the singleton has state, every possible state has to be tested against in every class using your singleton. else your test is not complete and thus useless.

note: i don't do unittests technically. only mental ones sometimes when thinking about my code.
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

Quote:Original post by TheMac
How are singletons bad programming, but globals are not?

If you make a class singleton, you can use it only as singleton and global. If you don't make a class singleton, you have option to use it as a global but also as a local, etc. Making a class singleton makes the code less reusable.

Btw, I'm not saying that globals are good programming practice either ;)
and we haven't said globals are good :)

but sometimes they fit your needs. question is, when do singletons fit your need and globals don't? singletons are much more limiting, when do you gain from it?

i'm all for limiting stuff in your code, that's why you shouldn't use globals. but i never limit classes, i always limit objects. limiting scope and all is great, limiting functionality is just bad.
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

Quote:Original post by ToohrVyk
I think you have a problem with the generally accepted meaning of principles. A principle is something you can follow while writing code. It makes sense to follow the open-closed principle, because it dictates that some things should be done ("your classes should be open to extension even if they are closed to modification"), but it doesn't make sense to "follow" polymorphism...


Good point, I somewhat overlooked that word. Just thought that the principles are separate from the paradigm but maybe only to a small extent. That's one reason I am learning functional programming to really see for myself if it's true that the design patterns used in OOP are not needed there.

Quote:Polymorphism and encapsulation are generally thought to be object-oriented tools, something you can use to build great object-oriented programs, but which you can also use to write messy heaps of developer pain—principles being what guides you to use the tools to achieve the former instead of the latter.


Agreed. Something happens in my head soon as someone mentions OOP and I get flash backs from the OOP spaghetti I have seen and also written myself.

This is a bit off topic... :)
My opinion: There might be some cases where a singleton is the right thing, though I lack experience there as I've never needed one ...

Quote:Original post by davepermen
but sometimes they fit your needs. question is, when do singletons fit your need and globals don't? singletons are much more limiting, when do you gain from it?

... but I don't like blanket statements (admittedly sometimes I make them unintentionally). Dave, the last time I used a global variable was somewhen around 2001. I began programming around 1999, afair. Maybe you can enlighten us with a usage scenario where you really need a unit- or program-scope mutable variable, before further requesting examples for correct use of singletons?


Quote:i'm all for limiting stuff in your code, that's why you shouldn't use globals.


Just to clarify: I guess you basically mean that it's a good thing to tighten the scope or lifetime of an object as much as possible? (just curious, that phrase of yours can be interpreted in many ways)

Quote:but i never limit classes, i always limit objects.

In which respect exactly do you limit it all?

Quote:limiting functionality is just bad.

I limit functionality all the time, especially when writing const correct code. Also, I am going to limit functionality to enable YAGNI principles (e.g. I will make the standard constructor, the standard copy constructor, and the copy assignment operator private by default, and introduce more freedom only when needed; you won't believe how many times that saved some buttes). Often, you will also see me making a class final, so no one can derive from it.
Original post by TheMac
Original post by the_edd
Quote:Original post by TheMac
I am going through this in my head and I can't understand why for one, singletons are hard to test in your unit tests.


You might be able to unit test a singleton, but you cannot unit test anything that uses that singleton.
Quote:

Not true, at work I replaced the way we do encryption with an encryption/decryption manager (singleton), changed the code in one class to one single call to the manager, and the unit test that was already in place continued to run with no problems.

In other words, I replaced some complex boilerplate code with the manager, and our tests still worked, so why are people saying its hard or impossible to test?


Just because your test still passes does not mean that it was or is a proper unit test. Do you factor out the encryption mechanism by using a mock or some other sort of unit testing dependency injection? If not, then you are not performing an actual unit test, merely a test.

Also, what you have created is a global function, which can be created in many different ways other than the singleton pattern, and I would say that in fact, the singleton pattern is the most naive way to achieve a global function. And as many people have said, if you are not keeping state with your singleton, then the difficulty of unit testing diminishes (as you can replace global functions through dependency injection in your testing if you designed it well), but it also shows that you have completely missed the purpose of the singleton pattern as well.

This topic is closed to new replies.

Advertisement