Timeline for So Singletons are bad, then what?
Current License: CC BY-SA 2.5
39 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jun 30, 2021 at 13:24 | comment | added | Glitch | It is possible to have conditional destruction of singletons so as to allow replacement despite the mutability. | |
Apr 24, 2020 at 8:51 | comment | added | dgrat | It seems for me that your answer is rather a guide for how to properly subclass than the usage of singletons. Unfortunately, these two things are not related. | |
Sep 16, 2019 at 11:32 | comment | added | Sazzad Hissain Khan |
Inability to subclass not true for singleton class
|
|
Aug 26, 2019 at 16:32 | comment | added | DPM | Couple of questions. Why the inability to subclass is a problem if you want a single instance? Why do you mention inability to use interfaces, when a singleton could implement an interface. Maybe I didn't get it. | |
Jun 28, 2019 at 14:26 | comment | added | Bastien Vandamme | Accessible via a global, static instance field; > This is a fact. I don't see why it is bad. Created either on program initialization or upon first access; > Nice. No public constructor (cannot instantiate directly); > So what? Never explicitly freed (implicitly freed on program termination). --> Yes but like many other mechanism and I hope if you decided to use it is because you know what you do. Of course using singleton to just do a stupid call is stupid. | |
Sep 9, 2018 at 13:48 | comment | added | yeoman | Your caches have dependencies on specific dbms syntax and drivers? :D | |
Mar 26, 2018 at 3:14 | comment | added | David Chen | @Aaronaught I got a bit confused about the last graph. 1. Does the Cache Interfaces request data from the same instance of Cache (Generic)? 2. Does the Cache (Generic) hold references of Repository Interfaces, and use them to query data from the server? Your answer is really excellent and I'd like to learn more thoroughly from it! | |
Mar 24, 2017 at 15:39 | comment | added | user666412 | As in "Difficult to parallelize in the case of mutable state (requires extensive locking)" -- isn't this a problem with every single instance as well? | |
Jun 3, 2016 at 18:55 | comment | added | Slagathor | Great answer! Do anyone have a link to an example where this is done? To get a even better understanding of it? I'm in the process of experimenting with switching out my singleton myself. | |
Jun 8, 2015 at 13:28 | comment | added | crush | I'm really surprised that there is no mention in any of the answers about how Singleton and Service Locator patterns create hidden complexity. I believe that is one of the stronger reasons to leave Singleton dead. | |
Sep 19, 2014 at 4:59 | comment | added | Aaronaught | @Peter: Those two concepts aren't necessarily related. In the SOLID guidelines, they are the "D" and the "I" respectively. Both good practices, both independent of each other. | |
Sep 10, 2014 at 0:40 | comment | added | Peter | "Dependency Injection" a.k.a. interfaces. | |
Jun 25, 2014 at 3:40 | comment | added | Aaronaught | @Pacerier: The fundamental basis of the singleton pattern is its absolute and exclusive control over object lifetime. The instance cannot be created or destroyed by anyone else, lest it invalidate the guarantees made by a singleton. So yes, this is a matter of definition; an instance with a public destructor is ipso facto not a true singleton. | |
Jun 25, 2014 at 1:11 | comment | added | Pacerier | @Aaronaught, Do you mean that a singleton implementation that allows explicit freeing is no longer considered a "singleton" simply by definition? | |
Jun 25, 2014 at 1:08 | comment | added | Aaronaught | @Pacerier: No, they aren't. Read the answer. The Singleton pattern is intended to have an object lifetime equivalent to the application itself. Therefore, it can't be freed. (Of course, in non-GC'ed languages it can be freed, but it is illegal to do so.) Please feel free to link to a Singleton implementation that permits this behaviour if you disagree. | |
Jun 25, 2014 at 1:01 | comment | added | Pacerier | @Aaronaught, Why do you say that singletons are never explicitly freed? I do actually remember seeing singletons that are explicitly freed. | |
Apr 9, 2014 at 19:27 | comment | added | donquixote | There are two meanings of "single instance". 1. Your application uses only one instance, (and you want every part of the application to have access to that single instance). 2. You want to block "new Foo()" from being called more than once in the same process. A lot of trouble comes from this second idea, which imo is quite pointless. I have never seen a case where restricting the use of "new Foo()" would be a good idea. | |
Feb 1, 2014 at 1:53 | comment | added | Aaronaught |
@tieTYT: No, the repositories reference the various abstract cache types; the concrete cache classes below are implementations of the abstract caches. This is one possible implementation. Another would be a decorator implementation where the cache actually implements IMediaRepository and wraps the real IMediaRepository , although you really have to use an IoC container in order to make effective use of that pattern. Any of these are, of course, still better than the Singleton pattern.
|
|
Jan 31, 2014 at 13:15 | comment | added | Erik Engheim | @Dax Fohl singletons are to prevent multiple instances from being created. You use getInstance() instead of new. Just like with other objects sometimes you instantiate them and sometimes you pass them around. People create problems for themselves by ALWAYS using getInstance() instead of passing a pointer which they would have done for any other non singleton class. | |
Jan 31, 2014 at 6:42 | comment | added | Dax Fohl |
@AdamSmith if you're going to pass it around rather than access through the getInstance() then there's no need to add the singleton boilerplate code in the first place. conversely you just want to "ensure" one instance then that means you're setting yourself up for the (ab)use of the getInstance() method. if there's no getInstance() then people can't abuse it.
|
|
Jan 30, 2014 at 16:49 | comment | added | Daniel Kaplan | @Lucas ah, so is he saying the impl of that Cache class uses those interfaces on the side but implements the interfaces below? | |
Jan 30, 2014 at 16:37 | comment | added | Lucas | @tieTYT: He was just pointing out that a full design would have to access the data through a repository interface and that the Cache will mediate the repositories' access to the underlying data store. | |
Jan 30, 2014 at 15:53 | comment | added | Daniel Kaplan | I'm not sure if I understand this last picture or not. Why are there interfaces on the side? How are these interfaces different from the ones below the cache? | |
Jan 30, 2014 at 14:52 | comment | added | futlib | Great explanation of DI, and I've been using DI extensively in the last few years. But I'd like to point out that occasionally, doing DI manually is unreasonably cumbersome, and some languages don't support automatic DI well, e.g. C++. I've found service locators (implemented as singletons, yes) to be a good alternative in those cases, they've got only a few of the weaknesses of singletons you identified above. | |
Nov 14, 2013 at 0:37 | comment | added | Aaronaught |
@CodesInChaos: That's an interesting point, and actually demonstrates another way of implementing single instances without the problem-ridden Singleton pattern. Certain thread-safe classes like AsciiEncoding are single instance but are also constructable and inheritable. It's a fairly specialized implementation of a more general class of pools, like the ADO.NET connection pool. What's interesting about these is that the singleton-ness is an implementation detail and never exposed to the consumer. Encoding.ASCII is just a utility method, you could still subclass and create your own.
|
|
Nov 13, 2013 at 14:06 | comment | added | CodesInChaos |
There is one more condition to be the bad singleton pattern: Mutability or access to external mutable state. For example making something like AsciiEncoding a singleton with a static accessor would be fine since any possible instance of it would be equivalent.
|
|
Nov 13, 2013 at 13:39 | comment | added | cregox | @Wilbert I hear you. I read the bullet list part again. I see what you mean. And now I do agree. That is indeed the meat of the answer... But I still think there's something missing there. It's like you and Aaron are both first assuming Singleton are bad, then drawing this conclusion. Singleton is indeed a subsection of single instance. But it's also a subsection of a "kind of global var". As such, a single instance can't really replace a singleton just as much as it can't be global. So, that's cherry picking. | |
Nov 13, 2013 at 13:29 | comment | added | Wilbert | @Cawas I feel that the meat of this answer is the distinction between single-instance and singleton. Singleton is bad, single-instance is not. Dependency Injection is a nice, general way to use single-instances without having to use singletons. | |
Nov 13, 2013 at 13:07 | comment | added | cregox | @Wilbert Reading your comment I feel you didn't really read my links (there are many links, dude, with many big reads). You're being too much pretentious thinking it's all in this answer. From the "question quote" and beyond all Aaron do is address the problem in the question about caching. And that has nothing to do with singletons being good or bad, as he just proposes one good architecture solution for a singular problem. So, the only part addressing singleton issues is the bullet list. Big deal. | |
Nov 13, 2013 at 12:56 | comment | added | Wilbert | @Cawas and Adam Smith - Reading your links I get the feeling you didn't really read this answer - everything is already in there. | |
Nov 13, 2013 at 12:40 | comment | added | cregox | Or you could say singletons are actually good and use Toolbox (i.e. check my answer in this very question)! | |
Nov 12, 2013 at 13:13 | comment | added | cregox |
I completely agree with @AdamSmith. You're not really giving an alternative to singleton Aaron, unless you mean we should simply use static instead, which is a bad advice. Static and singletons have their niche, the problem is the misusage of them. || Now that's good and simple writing on your tumblr, Mr Smith. I also advice for more complex reading on the same subject, this great article, more than 10 years old and still much useful: ibm.com/developerworks/webservices/library/co-single/index.html
|
|
Sep 19, 2013 at 11:14 | comment | added | Erik Engheim | @Aaronaught I did, but you have a definition of singleton pattern, and I don't see a problem with any of the points. The problems you list don't follow from merely following the singleton pattern bullet list you present. | |
Sep 18, 2013 at 0:09 | comment | added | Aaronaught | @AdamSmith: Did you actually read any of this answer? Your question is answered in the first two paragraphs. Singleton Pattern !== Single Instance. | |
Sep 17, 2013 at 13:29 | comment | added | Erik Engheim | Why can't the Cache be a singleton? Is it not a singleton if you pass it around and use dependency injection? Singleton is just about limiting ourselves to one instance, not about how it is accessed right? See my take on this: assoc.tumblr.com/post/51302471844/the-misunderstood-singleton | |
Jan 23, 2013 at 1:11 | comment | added | MrLane | First post I have ever read which actually explains DI as an alternative to global state. Thanks for the time and effort put into this. We are all better off as a result of this post. | |
Jan 27, 2011 at 23:32 | vote | accept | Bobby Tables | ||
Jan 27, 2011 at 19:10 | history | edited | Aaronaught | CC BY-SA 2.5 |
added 426 characters in body
|
Jan 27, 2011 at 18:53 | history | answered | Aaronaught | CC BY-SA 2.5 |