views:

603

answers:

9

This is admittedly a rather loose question. My current understanding of singletons is that they are a class that you set up in such a way that only one instance is ever created.

This sounds a lot like a static class to me. The main differnce being that with a static class you don't / can't instance it, you just use it such as Math.pi(). With a singletong class, you would still need to do something like

singleton mySingleton = new singleton();
mysingleton.set_name("foo");
singleton otherSingleton = new singleton();
// correct me if i am wrong, but mysingleton == othersingleton right now, yes?
// this the following should happen?
otherSingleston.set_name("bar");
mysingleton.report_name(); // will output "bar" won't it?

Please note, I am asking this language independently, more about the concept. So I am not so worried about actually how to coed such a class, but more why you would wan't to and what thing you would need to consider.

A: 

Not all languages have "static classes" (for example C++ doesn't have them).

Again with the C++ example, adding static variables to a class is a pain because you need to put them in both the header and the .cpp file, so a singleton in that case is very useful.

Every language is different. I guess in C# they are not very useful (and in fact, from what I know, they are not used very often)

Andreas Bonini
C++ allows static member functions, and therefore supports static classes (which are, roughly speaking, nothing more than classes with only static member functions).
Marcelo Cantos
Been a while since I played with C++ in that way. Didn't realise static was so 'limited'. Don't you have things like the maths classes that already there for you to use? or are they initialised already in the libraries?
thecoshman
@Marcelo: by `static classes` I meant something like the static keyword in C#.
Andreas Bonini
@thecoshman: there is no such thing as "maths classes" in C++. There is the C math library, which uses normal global functions.
Andreas Bonini
@Andreas, that just means that C# has the notion of "static class" baked into its design. It doesn't mean that the concept is somehow unavailable for use in C++. In particular, it doesn't constitute an argument for the singleton pattern in C++. If you look it up in the GoF book, you won't see "lack of static classes in C++" as a rationale.
Marcelo Cantos
@Marcelo: I never stated such a thing.
Andreas Bonini
@Andreas Bonini: Am I just getting my self mixed up when I think that you can use `Math.pi()` in C++ or have I forgotten that I have actually instanced it at some stage? I swear that was a static class of maths functions, as well as other functions from other static classes.
thecoshman
If it was a static class it would have been Math::pi(), anyways no standard libraries uses 100% pure static classes (at least that I know of)
Andreas Bonini
Well, I suppose something like a Math's library is 99% of the time just functions that you want a value back out of. but you occasionally will want to work on some maths that involves storing values with in a maths object for a moment, and you may need to do it with a few things at once... some matrix maths probably... ugh
thecoshman
+1  A: 

Singletons are mostly useful when you want an interface to a singleton service, but you don't know until runtime which concrete class will be instantiated.

For instance, you might want to declare a central logging service, but only decide at runtime whether to hook in a file logger, stub logger, database logger, or message-queue logger.

Marcelo Cantos
What do you mean by singleton service? one that only has one instance?
thecoshman
+1  A: 
  1. Singleton is a very useful replacement of global variables, used all across the code.
  2. Singletons are usually not "new"ed or "delete"d, they tend to be initialized on first use and deleted along with program scope
  3. Singletons perfectly match for wrapping logging, configuration and other hardware-interfacing classes.
alemjerus
Singletons are not a good replacement for global variables. Used incorrectly, they have every disadvantage of global variables, and a couple extras for good measure. The only benefit of singletons over globals is that people that don't know better feel good about themselves because instead of using a global (which they know is bad, even if they don't know why not), they've used a Design Pattern, which is a Good Thing (even though they're getting every single problem that globals have).
kyoryu
@kyoryu: an ad hominem attack is not a good argument. It rather suggests a lack of good arguments.
Elise van Looij
@Elise: It's not an ad hominem. Globals are bad for a number of reasons - static linkage to dependencies, shared mutable state, and have the lifetime of the application (not a good thing). Singletons share all of those aspects. Singletons, used well, are either a) immutable or b) implement an interface and passed via dependency injection. Singletons are not commonly used in this fashion, they are more frequently used as a replacement for global variables, without actually solving the fundamental problems of globals.
kyoryu
I've been reading up on singletons but so far I've learned more about the various personality defects attributed to their users than about the pros and cons of the objects themselves. Thanks for sharing your thoughts on them, though. Two observations on your criteria for a good singleton: a) Immutability. NSApp, or rather its delegate, isn't (window can be set directly). [NSNotificationCenter defaultCenter] is not directly mutable but via its methods it is. b) Dependency injection is not applicable in Objective-C, but perhaps you meant 'passed to the client object to show the dependency'.
Elise van Looij
@Elise van Looij: That's exactly what dependency injection is. You don't need a framework. You just need to pass objects to their dependents rather than find them in static locations. (Incidentally, that's also one of the rules of the Actor model of computation...). Some of my response is frustration with people that reflexively go "globals bad!" and then use singletons throughout their code and debate the merits of various singleton implementations, without realizing that they're just using them as globals with a different name and more boilerplate.
kyoryu
@Elise van Looij: Also, look at Smalltalk, where classes are singleton objects subclassed from type Class. But since they're *objects* you can change the instance that they point to, among other things. If you really want to understand design patterns in general, look at Smalltalk.
kyoryu
@kyoryu, if I could stretch time and energy, I would look at Smalltalk. As it is, I fake it by browsing Stack Overflow. My Dependency injection comment was taken from http://stackoverflow.com/questions/309711/dependency-injection-framework-for-cocoa. However, others do use the term as you seem to but in an Objective-C context, like http://stackoverflow.com/questions/569940/whats-the-best-way-to-communicate-between-view-controllers. Anyway, our discussion has encouraged me to do the research and focus my thoughts and I thank you for that.
Elise van Looij
@Elise van Looij: No problem. And yes, the terms/techniques are used elsewhere, but many of them originated in Smalltalk, so it's a good place to look. Obj-C seems more Smalltalk-like than C++/Java/C#, FWIW. Singletons are often used to solve the problem of "how do I have a shared object between different consumer instances," when a Builder or Factory combined with Dependency Injection would be a more effective solution.
kyoryu
+15  A: 

The main advantage of a singleton over a class consisting of statics is that you can later easily decide that you need in fact more than one instance, e.g. one per thread.

However, in practice the main purpose of singletons is to make people feel less bad about having global variables.

A practical example for a good use of a singleton: you have an app that uses an SQL database and you need a connection pool. The purpose of such a pool is to reuse DB connection, so you definitely want all clients to use the same pool. Thus, having it as a singleton is the correct design. But one day you need the app to connect to a second DB server, and realize that you cannot have connections to different servers in the same pool. Thus your "one instance overall" singleton becomes "one instance per DB server".

Michael Borgwardt
*LOL* +1 for "Singletons are the political correct name for global variables on OO" ;-)
Aaron Digulla
So is a 'properly' formed singleton a sort of half way house between a normal class that you can instance as many times as you want in as many threads and a static class which can only be, for want of better word, instanced once... in all of your threads? Never dealt with multi threaded applications. So do static classes exist in the same state, even over multiple threads?
thecoshman
@thecoshman: the "one per thread" thing was just an example, it could just as well be a different criterium like "every 100th caller gets a new instance". But yeah, a static class would be the same over all threads, if your environment does shared-memory multithreading.
Michael Borgwardt
So where would that advantage be of being able to instance an object ever nth time? And should it really be left up to the class it self to impose such a limit? surely it would be better to have you class free to instanced as much as you want it, but impose a limit, if you really need it, by using it through/derived by another class? Sort of working on the theory of doing one thing amazingly.
thecoshman
@thecoshman again just an example, and not a particularly useful one. Edited post to add useful example.
Michael Borgwardt
Yer that new example really helps demonstrate when a singleton is wise. Basically, any-time you only 'want' one instance of something that in theory is not unique. But is not the idea of a singleton that it allows you to treat it like something you can instance lots of, but its really just the same instance?
thecoshman
"Thus, having it as a singleton is the correct design" I can't see how this logically follows from wanting all clients to use the same pool. There are certainly other, better, ways to achieve this than with a singleton.
Andreas Brinck
Singletons are often used for immutable values - true and false in Smalltalk are singletons (IIRC - also, they're not *actually* immutable...) or String.Empty in C#. Also, classes in Smalltalk are singletons - `MyClass new` actually sends a message 'new' to a singleton object 'MyClass' which is of class 'Class.' To understand design patterns (and especially singletons) you really need to know some Smalltalk.
kyoryu
I am with Andreas - just because all clients should re-use the same connection pool doesn't mean singleton is the right design - you could pass the connection pool to all clients as well.
MadKeithV
@Andreas, @MadKeithV: At the most basic level, "singleton" just means there is only one instance, and that is clearly correct for a connection pool. How you ensure that and how clients get access to that one instance is a separate matter. A static factoy method is indeed often not the best design. But dependency injection frameworks *also* have the notion of "singleton"
Michael Borgwardt
@Michael, at the most basic level, Singleton jumps through hoops to FORCE that there is only one instance. This is unnecessary, because you can simply create only one instance of any object and avoid all the downsides of singletons.The downsides of the hoops outweigh the benefits in the eyes of many people.
MadKeithV
+6  A: 

why you would wan't to

I wouldn't because singletons usually are very bad way to solve your problems. My recommendation to you is to avoid them completely.

There is no simple explanation for that. I can only throw in some ideas:

  • Singletons mostly represent global state (which is evil).
  • Correct dependency injection becomes impossible.

I suggest you read the rest in this Google employee's blog:

codethief
Five years ago I implemented a policy that says: "Never use singletons. If you are sure you need one convince your lead!".Got challenged twice in five years. End result was always the same:The non singleton solution was better.
Andreas
+1  A: 
MadKeithV
I can see what you mean if you have a class that just provides a few functions. I assume by 'free functions' you mean a function just declared any where for use anywhere. But having a class that has say a static variable that all instances can access, say in/de-crement as part con/de-structor to work as a counter of instances can be very 'clean' especially when coupled with a static function to get said variable, thus letting you know if you have some how lost track of an instance. you could even extend it to let you get pointers back to instances, let the class track what instances exist
thecoshman
A class that contains any non-static functionality is not a static class - it's a class with static members. This is often also a cause for concern in complex projects, but not as blatantly hackish as a class with ONLY static data and member functions.
MadKeithV
@MadKeithV Why do you say that a class with ONLY static data andfunctions is 'hackish'. Surely, flogging a dead horse with this example now, you have a maths help class, all you need is functions. And languages like C# you can't just have functions floating around, they need to be in a class, unless you stick them in your main class, but then you can't reuse the code as easily.
thecoshman
Why would I *want* a maths help class if I only need functions? If I can't do that, that's a language deficiency, and it's still a hack, even if it is a required hack to get the functionality you need.
MadKeithV
A: 

In addition to the other answers I'd have to say that Singletons can help you when you want a static class, but can't have it, because due to the design of your application it will be inheriting an instantiable class.

Manos Dilaverakis
+2  A: 

A little knowledge is a dangerous thing and Singletons are dangerous entities. In addition to written things above, I can emphasize the life-time management of Singleton objects are also important. In ACE framework, it is handled successfully. You can find the paper here: http://www.cs.wustl.edu/~schmidt/PDF/ObjMan.pdf

Please also note that singletons should be non-copyable classes. This pattern may seem to be the easiest one, but, on the contrary it is one of the difficult. Therefore, I ask to candidates about this evil points in Singletons.

baris_a
A: 

There's two ways to use singletons.

  1. The way they should be used. Typically with immutable variables (C#'s String.Empty, classes in Smalltalk, etc.). This is approximately 1% of singleton usage.
  2. As a replacement for global variables. This is bad. The root cause of this is people that want to share common objects without understanding how to properly use a Builder. Use of Singletons in this fashion is typically a sign of a lack of deep understanding of object-oriented design.
kyoryu