Purpose of singletons in programming
Asked Answered
T

10

59

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 difference being that with a static class you don't / can't instance it, you just use it such as Math.pi(). With a singleton class, you would still need to do something like

singleton firstSingleton = new singleton();
firstSingleton.set_name("foo");

singleton secondSingleton = new singleton();

Correct me if i am wrong, but firstSingleton == secondSingleton right now, yes?

secondSingleston.set_name("bar");
firstSingleton.report_name(); // will output "bar" won't it?

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

Truthvalue answered 31/3, 2010 at 7:23 Comment(1)
I lot of people have said that singletons are basically just a way of getting global variables, and this is 'evil'. But surely there are times when global variables are useful? how is it that singletons 'global variables'Truthvalue
M
58

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".

Mayapple answered 31/3, 2010 at 7:31 Comment(13)
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?Truthvalue
@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.Mayapple
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.Truthvalue
@Truthvalue again just an example, and not a particularly useful one. Edited post to add useful example.Mayapple
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?Truthvalue
"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.Austinaustina
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.Falsity
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.Frankie
@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"Mayapple
@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.Frankie
What... The advantage of singletons is that you can easily decide to have more than one instance? How does that even make sense? The entire purpose of a singleton is to make an unbreakable promise that one, and exactly one, instance is going to exist, at all times.Vannavannatta
@jalf: Wrong. If that were the entire purpose, you could just as well use a class with only static methods and fields. That would make the promise a whole lot more unbreakable. But by making it an object, you always have potentially more than one instance. Sometimes that turns out to be what you need later on.Mayapple
@Michael: Only static methods: MyClass::foo(), as singleton: MyClass::getInstance().foo(). It's nothing more than search + replace for MyClass:: with a bit of caution as to not overwrite out-of-class definitions. Both are equally bad.Map
S
14

why you would wan't to

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

The main reasons are:

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

I suggest you read the rest (including thorough explanations) in this Google employee's blog:

Stepaniestepbrother answered 31/3, 2010 at 7:32 Comment(1)
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.Faraday
F
4

Like others have said:

  • Singletons are global variables by another name.
  • Singletons are usually a bad idea.
  • Singletons could be replaced by "monostate" classes - classes that have apparently normal construction / destruction semantics but all share the same state.

Note that in my opinion "static classes" are usually also a bad idea, a hackish workaround for a language that does not allow free functions, or for sharing state between a bunch of functions without wanting to pass that state as a parameter.

In my experience nearly all designs with singletons or static classes can be turned into something better, more easily understood and more flexible by getting rid of those constructs.

Edit: By request, why most singletons are global variables by another name.

In most of the languages I know, most singleton classes are accessed through a static member function of that class. The single instance is available to all code that has access to the definition of the singleton class. This is a global variable - all code that includes the class could be making modifications to the single instance of your singleton.
If you do not use the static member function (or some static factory method which has the same implications), but instead pass the singleton object to all clients that need it, then you would have no need for the singleton pattern, just pass the same object to all clients.

Frankie answered 31/3, 2010 at 7:42 Comment(4)
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 existTruthvalue
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.Frankie
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.Truthvalue
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.Frankie
B
2

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.

Berber answered 31/3, 2010 at 7:27 Comment(1)
What do you mean by singleton service? one that only has one instance?Truthvalue
S
2

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.

Sanctitude answered 31/3, 2010 at 8:16 Comment(0)
F
1

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.
Falsity answered 31/3, 2010 at 8:18 Comment(0)
H
0

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)

Hypsometer answered 31/3, 2010 at 7:26 Comment(9)
C++ allows static member functions, and therefore supports static classes (which are, roughly speaking, nothing more than classes with only static member functions).Berber
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?Truthvalue
@Marcelo: by static classes I meant something like the static keyword in C#.Hypsometer
@thecoshman: there is no such thing as "maths classes" in C++. There is the C math library, which uses normal global functions.Hypsometer
@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.Berber
@Marcelo: I never stated such a thing.Hypsometer
@Faraday 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.Truthvalue
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)Hypsometer
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... ughTruthvalue
E
0
  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.
Enravish answered 31/3, 2010 at 7:29 Comment(8)
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).Falsity
@kyoryu: an ad hominem attack is not a good argument. It rather suggests a lack of good arguments.Dardani
@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.Falsity
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'.Dardani
@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.Falsity
@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.Falsity
@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 #310211. However, others do use the term as you seem to but in an Objective-C context, like #570440. Anyway, our discussion has encouraged me to do the research and focus my thoughts and I thank you for that.Dardani
@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.Falsity
A
0

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.

Aleurone answered 31/3, 2010 at 8:8 Comment(0)
S
0

It is pretty much another word for "Global Variables", which has its pros and cons. However, the only thing that would make the Singleton worthy your time is it assures some sort of "maintainability" in the future for your code in case you decided that there is a actually a need for more than one "instance" of that class.

Swinish answered 4/12, 2022 at 19:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.