The singleton pattern is a fully paid up member of the GoF's patterns book, but it lately seems rather orphaned by the developer world. I still use quite a lot of singletons, especially for factory classes, and while you have to be a bit careful about multithreading issues (like any class actually), I fail to see why they are so awful.
Stack Overflow especially seems to assume that everyone agrees that Singletons are evil. Why?
Please support your answers with "facts, references, or specific expertise"
Paraphrased from Brian Button:
They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.
They violate the single responsibility principle: by virtue of the fact that they control their own creation and lifecycle.
They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.
They carry state around for the lifetime of the application. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.
Answered 2023-09-20 20:55:15
Singletons solve one (and only one) problem.
Resource Contention.
If you have some resource that
(1) can only have a single instance, and
(2) you need to manage that single instance,
you need a singleton.
There aren't many examples. A log file is the big one. You don't want to just abandon a single log file. You want to flush, sync and close it properly. This is an example of a single shared resource that has to be managed.
It's rare that you need a singleton. The reason they're bad is that they feel like a global and they're a fully paid up member of the GoF Design Patterns book.
When you think you need a global, you're probably making a terrible design mistake.
Answered 2023-09-20 20:55:15
Some coding snobs look down on them as just a glorified global. In the same way that many people hate the goto statement there are others that hate the idea of ever using a global. I have seen several developers go to extraordinary lengths to avoid a global because they considered using one as an admission of failure. Strange but true.
In practice the Singleton pattern is just a programming technique that is a useful part of your toolkit of concepts. From time to time you might find it is the ideal solution and so use it. But using it just so you can boast about using a design pattern is just as stupid as refusing to ever use it because it is just a global.
Answered 2023-09-20 20:55:15
Misko Hevery, from Google, has some interesting articles on exactly this topic...
Singletons are Pathological Liars has a unit testing example that illustrates how singletons can make it difficult to figure out dependency chains and start or test an application. It is a fairly extreme example of abuse, but the point that he makes is still valid:
Singletons are nothing more than global state. Global state makes it so your objects can secretly get hold of things which are not declared in their APIs, and, as a result, Singletons make your APIs into pathological liars.
Where have all the Singletons Gone makes the point that dependency injection has made it easy to get instances to constructors that require them, which alleviates the underlying need behind the bad, global Singletons decried in the first article.
Answered 2023-09-20 20:55:15
I think the confusion is caused by the fact that people don't know the real application of the Singleton pattern. I can't stress this enough. Singleton is not a pattern to wrap globals. Singleton pattern should only be used to guarantee that one and only one instance of a given class exists during run time.
People think Singleton is evil because they are using it for globals. It is because of this confusion that Singleton is looked down upon. Please, don't confuse Singletons and globals. If used for the purpose it was intended for, you will gain extreme benefits from the Singleton pattern.
Answered 2023-09-20 20:55:15
setInstance
methods before.) That hardly matters, though -- that weenie that "needed" a singleton also didn't know a freaking thing about encapsulation or what's wrong with mutable global state, so he helpfully(?) provided setters for every. single. field. (And yes, this happens. A lot. Nearly every singleton i've ever seen in the wild was mutable by design, and often embarassingly so.) - anyone goto
, etc. They might work in many cases, but frankly, "works" isn't enough -- if you want to go against conventional wisdom, you had better be able to demonstrate how your approach is better than the conventional solutions. And i've yet to see such a case for the Singleton pattern. - anyone getInstance
or similarly named method, and prevents the existence of a second instance. Frankly, at that point, you might as well not even have the one instance. - anyone One rather bad thing about singletons is that you can't extend them very easily. You basically have to build in some kind of decorator pattern or some such thing if you want to change their behavior. Also, if one day you want to have multiple ways of doing that one thing, it can be rather painful to change, depending on how you lay out your code.
One thing to note, if you DO use singletons, try to pass them in to whoever needs them rather than have them access it directly... Otherwise if you ever choose to have multiple ways of doing the thing that singleton does, it will be rather difficult to change as each class embeds a dependency if it accesses the singleton directly.
So basically:
public MyConstructor(Singleton singleton) {
this.singleton = singleton;
}
rather than:
public MyConstructor() {
this.singleton = Singleton.getInstance();
}
I believe this sort of pattern is called dependency injection and is generally considered a good thing.
Like any pattern though... Think about it and consider if its use in the given situation is inappropriate or not... Rules are made to be broken usually, and patterns should not be applied willy nilly without thought.
Answered 2023-09-20 20:55:15
getInstance()
, then (b) is not quite true anymore. - anyone getInstance()
, you've effectively tossed out the one useful difference between the Singleton pattern and an ordinary reference. As far as the rest of the code is concerned, singleness is no longer a property. Only the caller of getInstance()
ever needs to know or even care how many instances there are. With only one caller, it costs more in effort and flexibility for the class to reliably enforce singleness than it does to have the caller simply store a reference and reuse it. - anyone The singleton pattern is not a problem in itself. The problem is that the pattern is often used by people developing software with object-oriented tools without having a solid grasp of OO concepts. When singletons are introduced in this context they tend to grow into unmanageable classes that contain helper methods for every little use.
Singletons are also a problem from a testing perspective. They tend to make isolated unit-tests difficult to write. Inversion of control (IoC) and dependency injection are patterns meant to overcome this problem in an object-oriented manner that lends itself to unit testing.
In a garbage collected environment singletons can quickly become an issue with regard to memory management.
There is also the multi-threaded scenario where singletons can become a bottleneck as well as a synchronization issue.
Answered 2023-09-20 20:55:15
A singleton gets implemented using a static method. Static methods are avoided by people who do unit testing because they cannot be mocked or stubbed. Most people on this site are big proponents of unit testing. The generally most accepted convention to avoid them is using the inversion of control pattern.
Answered 2023-09-20 20:55:15
Singleton
class. However, that immensely complicates the testing process. For one, now you need to be able to unload classes at will (not really an option in most languages), or start a new VM for each test (read: tests may take thousands of times as long). For two, though, the dependency on Singleton
is an implementation detail that is now leaking all over your tests. - anyone Singletons are also bad when it comes to clustering. Because then, you do not have "exactly one singleton" in your application anymore.
Consider the following situation: As a developer, you have to create a web application which accesses a database. To ensure that concurrent database calls do not conflict each other, you create a thread-save SingletonDao
:
public class SingletonDao {
// songleton's static variable and getInstance() method etc. omitted
public void writeXYZ(...){
synchronized(...){
// some database writing operations...
}
}
}
So you are sure that only one singleton in your application exists and all database go through this one and only SingletonDao
. Your production environment now looks like this:
Everything is fine so far.
Now, consider you want to set up multiple instances of your web application in a cluster. Now, you suddenly have something like this:
That sounds weird, but now you have many singletons in your application. And that is exactly what a singleton is not supposed to be: Having many objects of it. This is especially bad if you, as shown in this example, want to make synchronized calls to a database.
Of course this is an example of a bad usage of a singleton. But the message of this example is: You can not rely that there is exactly one instance of a singleton in your application - especially when it comes to clustering.
Answered 2023-09-20 20:55:15
Answered 2023-09-20 20:55:15
Unlike other answers I don't want to talk about what is wrong with Singletons but to show you how powerful and awesome they are when used correctly!
You can map MyModel
to a TestMyModel
class that inherits from it, everywhere when MyModel
will be injected you will get TestMyModel
instead.
As I stated in the title, singletons are not about having a single instance.
Answered 2023-09-20 20:55:15
Settings
object which is accessible from any widget so that each widget knows about how to format displayed numbers. If it was not a globally accessible object I would have to inject it in constructor to each and every widget in the constructor and keep the reference to it as a member variable. This is a terrible waste of memory and time. - anyone Monopoly is the devil and singletons with non-readonly/mutable state are the 'real' problem...
After reading Singletons are Pathological Liars as suggested in jason's answer I came across this little tidbit that provides the best presented example of how singletons are often misused.
Global is bad because:
- a. It causes namespace conflict
- b. It exposes the state in a unwarranted fashion
When it comes to Singletons
- a. The explicit OO way of calling them, prevents the conflicts, so point a. is not an issue
- b. Singletons without state are (like factories) are not a problem. Singletons with state can again fall in two categories, those which are immutable or write once and read many (config/property files). These are not bad. Mutable Singletons, which are kind of reference holders are the ones which you are speaking of.
In the last statement he's referring to the blog's concept of 'singletons are liars'.
How does this apply to Monopoly?
To start a game of monopoly, first:
Now, for anybody who hasn't really played monopoly, these standards are ideal at best. A defeat in monopoly is hard to swallow because, monopoly is about money, if you lose you have to painstakingly watch the rest of the players finish the game, and losses are usually swift and crushing. So, the rules usually get twisted at some point to serve the self-interest of some of the players at the expense of the others.
So you're playing monopoly with friends Bob, Joe, and Ed. You're swiftly building your empire and consuming market share at an exponential rate. Your opponents are weakening and you start to smell blood (figuratively). Your buddy Bob put all of his money into gridlocking as many low-value properties as possible but his isn't receiving a high return on investment the way he expected. Bob, as a stroke of bad luck, lands on your Boardwalk and is excised from the game.
Now the game goes from friendly dice-rolling to serious business. Bob has been made the example of failure and Joe and Ed don't want to end up like 'that guy'. So, being the leading player you, all of a sudden, become the enemy. Joe and Ed start practicing under-the-table trades, behind-the-back money injections, undervalued house-swapping and generally anything to weaken you as a player until one of them rises to the top.
Then, instead of one of them winning, the process starts all over. All of a sudden, a finite set of rules becomes a moving target and the game degenerates into the type of social interactions that would make up the foundation of every high-rated reality TV show since Survivor. Why, because the rules are changing and there's no consensus on how/why/what they're supposed to represent, and more importantly, there's no one person making the decisions. Every player in the game, at that point, is making his/her own rules and chaos ensues until two of the players are too tired to keep up the charade and slowly give up.
So, if a rulebook for a game accurately represented a singleton, the monopoly rulebook would be an example of abuse.
How does this apply to programming?
Aside from all of the obvious thread-safety and synchronization issues that mutable singletons present... If you have one set of data, that is capable of being read/manipulated by multiple different sources concurrently and exists during the lifetime of the application execution, it's probably a good time to step back and ask "am I using the right type of data structure here".
Personally, I have seen a programmer abuse a singleton by using it as some sort of twisted cross-thread database store within an application. Having worked on the code directly, I can attest that it was a slow (because of all the thread locks needed to make it thread-safe) and a nightmare to work on (because of the unpredictable/intermittent nature of synchronization bugs), and nearly impossible to test under 'production' conditions. Sure, a system could have been developed using polling/signaling to overcome some of the performance issues but that wouldn't solve the issues with testing and, why bother when a 'real' database can already accomplish the same functionality in a much more robust/scalable manner.
A Singleton is only an option if you need what a singleton provides. A write-one read-only instance of an object. That same rule should cascade to the object's properties/members as well.
Answered 2023-09-20 20:55:15
Singleton.getInstance()
. A language that supports reflection might be able to work around that by setting the field where the One True Instance is stored. IMO, though, tests become a bit less trustworthy once you've taken to monkeying around with another class's private state. - anyone See Wikipedia Singleton_pattern
It is also considered an anti-pattern by some people, who feel that it is overly used, introducing unnecessary limitations in situations where a sole instance of a class is not actually required.[1][2][3][4]
References (only relevant references from the article)
Answered 2023-09-20 20:55:15
My answer on how Singletons are bad is always, "they are hard to do right". Many of the foundational components of languages are singletons (classes, functions, namespaces and even operators), as are components in other aspects of computing (localhost, default route, virtual filesystem, etc.), and it is not by accident. While they cause trouble and frustration from time to time, they also can make a lot of things work a LOT better.
The two biggest screw ups I see are: treating it like a global & failing to define the Singleton closure.
Everyone talks about Singleton's as globals, because they basically are. However, much (sadly, not all) of the badness in a global comes not intrinsically from being global, but how you use it. Same goes for Singletons. Actually more so as "single instance" really doesn't need to mean "globally accessible". It is more a natural byproduct, and given all the bad that we know comes from it, we shouldn't be in such a hurry to exploit global accessibility. Once programmers see a Singleton they seem to always access it directly through its instance method. Instead, you should navigate to it just like you would any other object. Most code shouldn't even be aware it is dealing with a Singleton (loose coupling, right?). If only a small bit of code accesses the object like it is a global, a lot of harm is undone. I recommend enforcing it by restricting access to the instance function.
The Singleton context is also really important. The defining characteristic of a Singleton is that there is "only one", but the truth is it is "only one" within some kind of context/namespace. They are usually one of: one per thread, process, IP address or cluster, but can also be one per processor, machine, language namespace/class loader/whatever, subnet, Internet, etc.
The other, less common, mistake is to ignore the Singleton lifestyle. Just because there is only one doesn't mean a Singleton is some omnipotent "always was and always will be", nor is it generally desirable (objects without a begin and end violate all kinds of useful assumptions in code, and should be employed only in the most desperate of circumstances.
If you avoid those mistakes, Singletons can still be a PITA, bit it is ready to see a lot of the worst problems are significantly mitigated. Imagine a Java Singleton, that is explicitly defined as once per classloader (which means it needs a thread safety policy), with defined creation and destruction methods and a life cycle that dictates when and how they get invoked, and whose "instance" method has package protection so it is generally accessed through other, non-global objects. Still a potential source of trouble, but certainly much less trouble.
Sadly, rather than teaching good examples of how to do Singletons. We teach bad examples, let programmers run off using them for a while, and then tell them they are a bad design pattern.
Answered 2023-09-20 20:55:15
It's not that singletons themselves are bad but the GoF design pattern is. The only really argument that is valid is that the GoF design pattern doesn't lend itself in regards to testing, especially if tests are run in parallel.
Using a single instance of an class is a valid construct as long as you apply the following means in code:
Make sure the class that will be used as a singleton implements an interface. This allows stubs or mocks to be implemented using the same interface
Make sure that the Singleton is thread-safe. That's a given.
The singleton should be simple in nature and not overly complicated.
During the runtime of you application, where singletons need to be passed to a given object, use a class factory that builds that object and have the class factory pass the singleton instance to the class that needs it.
During testing and to ensure deterministic behavior, create the singleton class as separate instance as either the actual class itself or a stub/mock that implements its behavior and pass it as is to the class that requires it. Don't use the class factor that creates that object under test that needs the singleton during test as it will pass the single global instance of it, which defeats the purpose.
We've used Singletons in our solutions with a great deal of success that are testable ensuring deterministic behavior in parallel test run streams.
Answered 2023-09-20 20:55:15
Vince Huston has these criteria, which seem reasonable to me:
Singleton should be considered only if all three of the following criteria are satisfied:
- Ownership of the single instance cannot be reasonably assigned
- Lazy initialization is desirable
- Global access is not otherwise provided for
If ownership of the single instance, when and how initialization occurs, and global access are not issues, Singleton is not sufficiently interesting.
Answered 2023-09-20 20:55:15
I'd like to address the 4 points in the accepted answer, hopefully someone can explain why I'm wrong.
Why is hiding dependencies in your code bad? There are already dozens of hidden dependencies (C runtime calls, OS API calls, global function calls), and singleton dependencies are easy to find (search for instance()).
"Making something global to avoid passing it around is a code smell." Why isn't passing something around to avoid making it a singleton a code smell?
If you're passing an object through 10 functions in a call stack just to avoid a singleton, is that so great?
Single Responsibility Principle: I think this is a bit vague and depends on your definition of responsibility. A relevant question would be, why does adding this specific "responsibility" to a class matter?
Why does passing an object to a class make it more tightly coupled than using that object as a singleton from within the class?
Why does it change how long the state lasts? Singletons can be created or destroyed manually, so the control is still there, and you can make the lifetime the same as a non-singleton object's lifetime would be.
Regarding unit tests:
Answered 2023-09-20 20:55:15
I'm not going to comment on the good/evil argument, but I haven't used them since Spring came along. Using dependency injection has pretty much removed my requirements for singleton, servicelocators and factories. I find this a much more productive and clean environment, at least for the type of work I do (Java-based web applications).
Answered 2023-09-20 20:55:15
Singletons are bad from a purist point of view.
From a pratical point of view, a singleton is a trade-off developing time vs complexity.
If you know your application won't change that much they are pretty OK to go with. Just know that you may need to refactor things up if your requirements change in an unexpected way (which is pretty OK in most cases).
Singletons sometimes also complicate unit testing.
Answered 2023-09-20 20:55:15
There is nothing inherently wrong with the pattern, assuming it is being used for some aspect of your model which is truly single.
I believe the backlash is due to its overuse which, in turn, is due to the fact that it's the easiest pattern to understand and implement.
Answered 2023-09-20 20:55:15
Singleton is a pattern and can be used or abused just like any other tool.
The bad part of a singleton is generally the user (or should I say the inappropriate use of a singleton for things it is not designed to do). The biggest offender is using a singleton as a fake global variable.
Answered 2023-09-20 20:55:15
When you write code using singletons, say, a logger or a database connection, and afterwards you discover you need more than one log or more than one database, you’re in trouble.
Singletons make it very hard to move from them to regular objects.
Also, it’s too easy to write a non-thread-safe singleton.
Rather than using singletons, you should pass all the needed utility objects from function to function. That can be simplified if you wrap all them into a helper object, like this:
void some_class::some_function(parameters, service_provider& srv)
{
srv.get<error_logger>().log("Hi there!");
this->another_function(some_other_parameters, srv);
}
Answered 2023-09-20 20:55:15
Too many people put objects which are not thread safe in a singleton pattern. I've seen examples of a DataContext (LINQ to SQL) done in a singleton pattern, despite the fact that the DataContext is not thread safe and is purely a unit-of-work object.
Answered 2023-09-20 20:55:15
The problems with singletons is the issue of increased scope and therefore coupling. There is no denying that there are some of situations where you do need access to a single instance, and it can be accomplished other ways.
I now prefer to design around an inversion of control (IoC) container and allow the the lifetimes to be controlled by the container. This gives you the benefit of the classes that depend on the instance to be unaware of the fact that there is a single instance. The lifetime of the singleton can be changed in the future. Once such example I encountered recently was an easy adjustment from single threaded to multi-threaded.
FWIW, if it a PIA when you try to unit test it then it's going to PIA when you try to debug, bug fix or enhance it.
Answered 2023-09-20 20:55:15
Recent article on this subject by Chris Reath at Coding Without Comments.
Note: Coding Without Comments is no longer valid. However, The article being linked to has been cloned by another user.
Answered 2023-09-20 20:55:15
Singletons are NOT bad. It's only bad when you make something globally unique that isn't globally unique.
However, there are "application scope services" (think about a messaging system that makes components interact) - this CALLS for a singleton, a "MessageQueue" - class that has a method "SendMessage(...)".
You can then do the following from all over the place:
MessageQueue.Current.SendMessage(new MailArrivedMessage(...));
And, of course, do:
MessageQueue.Current.RegisterReceiver(this);
in classes that implement IMessageReceiver.
Answered 2023-09-20 20:55:15
Here is one more thing about singletons which nobody said yet.
In most cases "singletonity" is a detail of implementation for some class rather than characteristic of its interface. Inversion of Control Container may hide this characteristic from class users; you just need to mark your class as a singleton (with @Singleton
annotation in Java for example) and that's it; IoCC will do the rest. You don't need to provide global access to your singleton instance because the access is already managed by IoCC. Thus there is nothing wrong with IoC Singletons.
GoF Singletons in opposite to IoC Singletons are supposed to expose "singletonity" in the interface through getInstance() method, and so that they suffer from everything said above.
Answered 2023-09-20 20:55:15
Singletons aren't evil, if you use it properly & minimally. There are lot of other good design patterns which replaces the needs of singleton at some point (& also gives best results). But some programmers are unaware of those good patterns & uses the singleton for all the cases which makes the singleton evil for them.
Answered 2023-09-20 20:55:15
Because they are basically object oriented global variables, you can usually design your classes in such a way so that you don't need them.
Answered 2023-09-20 20:55:15
Firstly a class and its collaborators should firstly perform their intended purpose rather than focusing on dependents. Lifecycle management (when instances are created and when they go out of scope) should not be part of the classes responsibility. The accepted best practice for this is to craft or configure a new component to manage dependencies using dependency injection.
Often software gets more complicated it makes sense to have multiple independent instances of the Singleton class with different state. Committing code to simply grab the singleton is wrong in such cases. Using Singleton.getInstance()
might be ok for small simple systems but it doesn't work/scale when one might need a different instance of the same class.
No class should be thought of as a singleton but rather that should be an application of it's usage or how it is used to configure dependents. For a quick and nasty this does not matter - just luke hard coding say file paths does not matter but for bigger applications such dependencies need to be factored out and managed in more appropriate way using DI.
The problems that singleton cause in testing is a symptom of their hard coded single usage case/environment. The test suite and the many tests are each individual and separate something that is not compatible with hard coding a singleton.
Answered 2023-09-20 20:55:15