1798

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"


  • I have to say that using a singleton design has burned me recently as I have tried to adapt the code. As I do it in my free time, I'm almost too lazy to refactor this. Bad news for productivity. - Marcin
  • There's a lot of 'cons' in the answers, but I'd also like to see some good examples of when the pattern is good, to contrast with the bad... - DGM
  • I wrote a blog post on the subject a few months ago: jalf.dk/blog/2010/03/… -- and let me just say it outright. I can't personally think of a single situation where a singleton is the right solution. That doesn't mean such a situation does not exist, but... calling them rare is an understatement. - jalf
  • @AdamSmith it doesn't mean you have to, but it means you can access it like that. And if you don't intend to access it like that, then there's little reason to make it a singleton in the first place. So your argument is effectively "there's no harm in making a singleton if we don't treat it as a singleton. Yeah, great. My car also doesn't pollute if I don't drive in it. But then it's easier to just not acquire a car in the first place. ;) (full disclosure: I don't actually have a car) - jalf
  • The worst part of this whole topic is that the people who hate singletons rarely give concrete suggestions for what to use instead. The links to journal articles and self-published blogs all through this SO article, for example, go on and on about why not to use singletons (and they're all excellent reasons), but they're extremely slim on replacements. Lots of handwaving, though. Those of us trying to teach new programmers why not to use singletons don't have many good third-party counterexamples to point to, only contrived examples. It's wearying. - Ti Strga

30 답변


1182

Paraphrased from Brian Button:

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

  2. They violate the single responsibility principle: by virtue of the fact that they control their own creation and lifecycle.

  3. They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.

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


  • I disagree with you. Since comments are allowed only 600 chars, I have written a Blog Post to comment on this, please see the link below. jorudolph.wordpress.com/2009/11/22/singleton-considerations - Johannes Rudolph
  • On point 1 and 4, I think singletons are useful, and in fact almost perfect for caching data (especially from a DB). The increase in performance far outway the complexities involved in modeling unit tests. - Dai Bok
  • @Dai Bok: "caching data (especially from a DB)" use the proxy pattern to do this... - paxos1977
  • Wow, great responses. I probably used overly agressive wording here, so please keep in mind I was answering a negatively geared question. My answer was meant to be a short list of the 'anti patterns' that occur from bad Singleton usage. Full disclosure; I too use Singletons from time to time. There are more neutrally posed questions on SO that would make excellent forums for when Singletons can be considered a good idea. For instance, stackoverflow.com/questions/228164/… - Jim Burger
  • They aren't so great for caching in an multithreaded environment. You can easily defeat a cache with multiple threads fighting over a limited resource. [maintained by a singleton] - monksy

414

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.


  • Hardware is also an example right? Embedded systems have lots of hardware that might use singletons - or maybe one big one? <grin> - Jeff
  • Totally agree. There's a lot of determined "this practice is bad" talk floating around without any recognition that the practice may have its place. Often, the practice is only "bad" because it's frequently misused. There's nothing inherently wrong with the Singleton pattern as long as it's applied appropriately. - Damovisa
  • Real, by-principle singletons are very rare (and a printer queue certainly isn't one, and neither is a log file - see log4j). More often than not, hardware is a singleton by coincidence rather than by principle. All hardware connected to a PC is at best a coincidental singleton (think multiple monitors, mice, printers, sound cards). Even a 500 mio $ particle detector is a singleton by coincidence and budget constraints - which don't apply in software, thus: no singleton. In telecommunications, neither phone number nor the physical phone are singletons (think ISDN, call center). - digitalarbeiter
  • Hardware may have only one instance of a variety of resources, but hardware isn't software. There's no reason that a single serial port on a development board should be modeled as a Singleton. Indeed, modeling it so will only make it harder to port to the new board that has two ports! - dash-tom-bang
  • So you'd write two identical classes, duplicating a lot of code, just so you can have two singletons representing two ports? How about just using two global SerialPort objects? How about not modelling the hardware as classes at all? And why would you use singletons, which also imply global access? Do you want every function in your code to be able to access the serial port? - jalf

315

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.


  • The failure I see in Singleton is that folks use them instead of globals because they're somehow "better." The problem is (as I see it), that the things that Singleton brings to the table in these cases are irrelevant. (Construct-on-first-use is trivial to implement in a non-singleton, for example, even if it's not actually using the constructor to do it.) - dash-tom-bang
  • The reason "we" look down upon them is that "we" very frequently see them used wrong, and way too often. "We" do know that they have their place of cause. - Bjarke Freund-Hansen
  • @Phil, You stated "from time to time you might find it is the ideal solution and so use it". Ok, so exactly in which case would we find a singleton useful? - Pacerier
  • @Pacerier, whenever all of following conditions hold: (1) you only need one of something, (2) you need to pass that one thing as an argument in a large number of method calls, (3) you are willing to accept a chance of having to refactor someday in exchange for an immediate reduction in the size and complexity of your code by not passing the darn thing around everywhere. - antinome
  • I don't feel that this answers anything, it just says that 'sometimes it might fit, other times it may not'. OK, but why, and when? What makes this answer more than an argument to moderation? - Guildenstern

205

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.


  • Misko's articles on the subject are the best thing going around on it at the moment. - Chris Mayer
  • The first link doesn't actually address a problem with singletons, but rather assuming a static dependency inside the class. It's possible to fix the given example by passing in parameters, yet still use singletons. - DGM
  • @DGM: Exactly - in fact, there is a huge logical disconnect between the 'rationale' part of the article, and the 'Singletons are the cause' part. - Harper Shelby
  • Misko's CreditCard article is an extreme example of misuse of this pattern. - Alex
  • Reading the second article Singletons are actually part of the object model described. However, instead of being accessible globally these are private to the Factory objects. - FruitBreak

106

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.


  • What is that one instance, available throughout the app? Oh. Global. "Singleton is not a pattern to wrap globals" is either naive or misleading, as by definition, the pattern wraps a class around a global instance. - cHao
  • Of course you're free to create one instance of the class when your application starts, and inject that instance, through an interface, into anything that uses it. The implementation shouldn't care that there can be only one. - Scott Whitlock
  • @Dainius: There's really not, in the end. Sure, you don't get to arbitrarily replace the instance with another. (Except for those facepalm-inducing moments when you do. I've actually seen 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.) - cHao
  • @Dainius: To a large degree, we already have. "Prefer composition over inheritance" has been a thing for quite a while now. When inheritance is demonstrably the best solution, though, you are of course free to use it. Same thing with singletons, globals, threading, 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. - cHao
  • Lest we talk past each other, i'm not just talking about a globally available instance. There are plenty of cases for that. What i'm talking about (particularly when i say "capital-S Singleton") is the GoF's Singleton pattern, which embeds that single global instance in the class itself, exposes it via a 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. - cHao

70

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.


  • Heh, if you do this everywhere, then you would have to pass around a reference to the singelton everywhere also, and thus you don't have a singleton any more. :) (Which is usually a good thing IMO.) - Bjarke Freund-Hansen
  • @BjarkeFreund-Hansen - Nonsense, what are you talking about? A singleton is simply an instance of a class that is instatiated once. Referencing such an Singleton doesn't copy the actual object, it just references it - you still got the same object (read: Singleton). - M. Mimpen
  • @M.Mimpen: No, a capital-S Singleton (which is what is being discussed here) is an instance of a class that (a) guarantees that only one instance will ever exist, and (b) is accessed via the class's own built-in global point of access. If you have declared that nothing should be calling getInstance(), then (b) is not quite true anymore. - cHao
  • @cHao I don't follow you or you don't understand to whom I comment - which is to Bjarke Freund-Hansen. Bjarke states that having several references of a singleton results in have several singletons. That is certainly not true since there are no deep-copies. - M. Mimpen
  • @M.Mimpen: I take his comment to refer more to the semantic effect. Once you outlaw calls to 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. - cHao

65

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.


  • i know it is many year old thread. hi @Kimoz u said:- singletons can quickly become an issue with regard to memory management. would like to explain in more detail what kind of problem may arrive regarding singleton & garbage collection. - Thomas
  • @Kimoz, The question is asking "Why is the singleton pattern not a problem in itself?" and you have merely repeated the point but provided not even a single valid use case of the singleton pattern. - Pacerier
  • @Thomas, because a singleton by definition exists in only one instance. So, it's often complex to assign the only reference to null. It can be done, but it means that you fully control the point after which the singleton is not used in your app. And this is rare, and usually quite the opposite of what singleton enthusiast are looking for : a simple way to make a single instance always accessible. On some DI framworks like Guice or Dagger, it is not possible to get rid of a singleton and it stays forever in memory. (Though container provided singletons are far better than home made ones). - Snicolas

52

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.


  • That does sound more like a problem with the unit testing that can test objects (units), functions (units), whole libraries (units), but fail with anything static in class (also units). - v010dya
  • aren't you suppose to moc all external references anyway? If you are, then what's a problem to moc singleton, if not, are you really doing unit testing? - Dainius
  • @Dainius: Mocking instances is a lot less trouble than mocking classes. You could conceivably extract the class under test from the rest of the application and test with a fake 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. - cHao
  • Powermock can mock static stuff. - Snicolas
  • does mocking an object mean creating real object? If mocking does not create a real object then why does it matter whether the class is singleton or method is static? - Arun Raaj

42

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: Single Singleton

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:

Many singletons

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.


  • if you don't know how to implement singleton, you shouldn't do that. If you don't know what you are doing, you should find that first, and only after that do what you need. - Dainius
  • This is interesting, I have a question. So what exactly is the problem if singletons - each on a different machine/JVM - are connecting to a single database? Singletons scope is only for that particular JVM, and that is still true even in a cluster. Rather than just philosophically saying that this particular situation is bad because our intent was a single object across application I would be happy to see any technical problems that can arise because of this arrangement. - Saurabh Patil

34

  1. It is easily (ab)used as a global variable.
  2. Classes that depend on singletons are relatively harder to unit test in isolation.


30

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:

  • we establish the rules first so everybody is on the same page
  • everybody is given an equal start at the beginning of the game
  • only one set of rules is presented to avoid confusion
  • the rules aren't allowed to change throughout the game

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.


  • What if singleton cashes some data? - Yola
  • @Yola It would cut down on the number of writes if the singleton was scheduled to update on a predetermined and/or fixed schedule, thereby reducing thread contention. Still, you wouldn't be able to accurately test any of the code interacting with the singleton unless you mock a non-singleton instance that simulates the same usage. The TDD folks would probably have a fit but it would work. - Evan Plaice
  • @EvanPlaice: Even with a mock, you'd have some issues with code that says 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. - cHao

21

Singleton is not about single instance!

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 right!

  • Problem: Singleton can be a challenge in multi-threading environment
    Solution: Use a single threaded bootstrap process to initialize all the dependencies of your singleton.
  • Problem: It is hard to mock singletons.
    Solution: Use method Factory pattern for mocking
    MyModel myModel = Factory.inject(MyModel.class); You can map MyModel to TestMyModel class that inherits it, everywhere when MyModel will be injected you will get TestMyModel instread.
  • Problem: Singletons can cause memory leeks as they never disposed.
    Solution: Well, dispose them! Implement a callback in your app to properly dispose a singletons, you should remove any data linked to them and finally: remove them from the Factory.

As I stated at the title singleton are not about single instance.

  • Singletons improves readability: You can look at your class and see what singleton it injected to figure out what is it's dependencies.
  • Singletons improves maintenance: Once you removed a dependency from a class you just deleted some singleton injection, you don't need to go and edit a big link of other classes that just moved your dependency around(This is smelly code for me @Jim Burger)
  • Singletons improves memory and performance: When some thing happens in your application, and it takes a long chain of callbacks to deliver, you are wasting memory and performance, by using Singleton you are cutting the middle man, and improve your performance and memory usage(by avoiding unnecessary local variables allocations).


  • This doesn't address my main issue with Singletons which is they allow access to global state from any of the thousands of classes in your project. - LegendLength
  • That would be the purpose... - Ilya Gazman

21

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)

  1. ^ Alex Miller. Patterns I hate #1: Singleton, July 2007
  2. ^ Scott Densmore. Why singletons are evil, May 2004
  3. ^ Steve Yegge. Singletons considered stupid, September 2004
  4. ^ J.B. Rainsberger, IBM. Use your singletons wisely, July 2001


  • A description about the pattern doesn't explain why it is considered as evil... - Jrgns
  • Hardly fair: "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." Look at the references... Anyway there’s RTFM to me. - GUI Junkie

20

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.


16

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:

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

  2. Make sure that the Singleton is thread-safe. That's a given.

  3. The singleton should be simple in nature and not overly complicated.

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

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


  • +1, Finally an answer that addresses when a singleton may be valid. - Pacerier

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.


14

I'd like to address the 4 points in the accepted answer, hopefully someone can explain why I'm wrong.

  1. 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?

  2. 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?

  3. Why does passing an object to a class make it more tightly coupled than using that object as a singleton from within the class?

  4. 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:

  • not all classes need to be unit tested
  • not all classes that need to be unit tested need to change the implementation of the singleton
  • if they do need be unit tested and do need to change the implementation, it's easy to change a class from using a singleton to having the singleton passed to it via dependency injection.


  • 1. All those hidden dependencies? Those are bad too. Hidden dependencies are always evil. But in the case of the CRT and OS, they're already there, and they're the only way to get something done. (Try writing a C program without using the runtime or OS.) That ability to do stuff vastly outweighs their negatives. Singletons in our code don't get that luxury; since they're firmly within our sphere of control and responsibility, every usage (read: every additional hidden dependency) should be justifiable as the only reasonable way to get stuff done. Very, very few of them actually are. - cHao
  • 2. "Responsibility" is typically defined as "reason to change". A singleton ends up both managing its lifetime and doing its real job. If you change how the job is done or how the object graph is built, you have to change the class. But if you have other code build the object graph, and your class just does its real job, that initialization code can set up the object graph however it likes. Everything's much more modular and testable, because you can insert test doubles and tear everything down at will, and you're no longer relying on hidden moving parts. - cHao
  • @cHao: 1. It's good that you recognize that the "ability to do stuff vastly outweighs their negatives." An example would be a logging framework. It's evil to mandate passing a global logging object by dependency injection through layers of function calls if it means that developers are discouraged from logging. Hence, singleton. 3. Your tight coupling point is only relevant if you want clients of the class to control behavior via polymorphism. That's often not the case. - Jon
  • 4. I'm not sure that "cannot be destroyed manually" is a logical implication of "can be only one instance". If that's how you define singleton, then we're not talking about the same thing. All classes should not be unit tested. That's a business decision, and sometimes time-to-market or development cost will take precedence. - Jon
  • 3. If you don't want polymorphism, then you don't even need an instance. You might as well make it a static class, cause you're tying yourself to a single object and a single implementation anyway -- and at least then the API isn't lying to you as much. - cHao

13

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


  • aren't Spring beans, by default, Singletons? - slim
  • Yeah, but I mean 'coding' singletons. I haven't 'written a singleton' (i.e. with a private constructor yada yada yada as per design pattern) - but yes, with spring I am using a single instance. - prule
  • so when others do it, it's Ok (if I will use that after), but if others do it and I will not use it, it's evil? - Dainius

12

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.


  • My experience is that starting with singletons will really hurt you even in the short run, not counting the long run. This effect might me less so if the application is already existing for some time, and probably already infested with other singletons. Starting from scratch? Avoid them at all costs! Want a single instance of an object? Let a factory manage the instantiation of this object. - Sven
  • AFAIK Singleton is a factory method. Thus I don't get your recommendation. - tacone
  • "A factory" != "A factory_method that cannot be separated from the other useful stuff in the same class" - Sven

11

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.


  • I think the backlash has more to do with people practicing formalized unit testing realising that they are a nightmare to deal with. - Jim Burger
  • Not sure why this is at -1. It's not the most descriptive answer but he's not wrong either. - Outlaw Programmer

11

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.


  • Thanks Loki :) Exactly my point. The whole witch hunt reminds me of the goto debate. Tools are for people who know how to use them; using a tool you don't like may be dangerous for you so avoid it but DON'T tell others not to use / not to learn to use it properly. I'm not exactly "pro-singleton" but I like the fact that I have tool like that and I can feel where it is appropriate to use it. Period. - dkellner

8

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);
}


  • passing argument for every method is brilliant, it should go to at least top 10 ways how to pollute your api. - Dainius
  • That’s an obvious drawback, and one that should have been handled by the language, by means of arguments that somehow propagate into nested calls, but absent such support, it has to be done manually. Consider that even natural singletons, like an object representing the system clock, have potential for trouble. For example, how are you going to cover clock-dependent code (think multiple tariff electricity meter) with tests? - Roman Odaisky
  • depends what you are testing, if you aren't testing singleton, why you care how it behaves, if your 2 remote object depends on each other behavior, it's not singleton problem.. - Dainius
  • Could you provide which language would propagation into nested calls? - Dainius
  • If you have one module that depends on another and you don't know /can't moc it, you will have hard irregardless of is it singleton or not. People are using inheritance way to often, where they should use composition, but you don't say that inheritance are bad, and OOP should be avoid at all costs, because so many people are doing design mistakes there, or are you? - Dainius

7

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.


7

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.

http://geekswithblogs.net/AngelEyes/archive/2013/09/08/singleton-i-love-you-but-youre-bringing-me-down-re-uploaded.aspx


6

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.


  • In my opinion, "singletonity" is a run-time environment detail, and should not be considered by the programmer that wrote the class code. Rather, it is a consideration to be made by the class USER. only the USER knows how many instances are actually required. - Earth Engine

6

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.


  • And if I want to create a second message queue, with a smaller scope, why shouldn't I be allowed to reuse your code to create it? A singleton prevents that. But if you'd just created a regular message queue class, and then created one global instance to act as the "application scope" one, I could create a second instance for other use. But if you make the class a singleton, I'd have to write a second message queue class. - jalf
  • Also why shouldn't we just have a global CustomerOrderList so we can call it nicely from anywhere like MessageQueue? I believe the answer is the same for both: It's effectively making a global variable. - LegendLength

6

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.


  • many people write unsafe multi-threaded code, does that mean we should eliminate threads? - Dainius
  • @Dainius: In fact, yes. IMO the default concurrency model should be multi-process, with a way for two processes to (1) pass messages to each other easily, and/or (2) share memory on an as-needed basis. Threading is useful if you want to share everything, but you never really want that. It could be emulated by sharing the whole address space, but that would also be considered an anti-pattern. - cHao
  • @Dainius: And of course, that's assuming that honest-to-goodness concurrency is needed at all. Often all you want is to be able to do one thing while you wait for the OS to do something else. (Updating the UI while reading from a socket, for example.) A decent async API could make full-on threading unnecessary in a huge majority of cases. - cHao
  • so if you have huge matrix of data, that you need process, it's better to do that in single thread, because to many people might do that wrong.. - Dainius
  • @Dainius: In many cases, yes. (Threading could actually slow you down, if you add synchronization to the mix. This is a prime example of why multithreading shouldn't be most people's first thought.) In other cases, it'd be better to have two processes that share just the needed stuff. Of course, you'd have to arrange for the processes to share memory. But frankly, i see that as a good thing -- far better, at least, than defaulting to share-everything mode. It requires you to explicitly say (and so, ideally, to know) which parts are shared, and thus which parts need to be thread-safe. - cHao

4

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.


  • If you class isn't limited to once instance, you'll need static members in your class managed by semaphores which comes out to pretty much the same thing! What is your proposed alternative? - Jeach
  • I have a huge application with a "MainScreen" this screen opens up many smaller modal/non modal windows/ UI forms. IMHO I feel that the MainScreen should be a singleton so that for example, a widget somewhere in a far corner of the application wants to show its status in the MainScreen's status bar, all it has to do is MainScreen.getInstance().setStatus("Some Text"); What do you propose as an alternative ? Pass MainScreen all over the application ?? :D - Salvin Francis
  • @SalvinFrancis: What i'd recommend is, you stop having objects that care about stuff they shouldn't care about and sneak across the app to mess around with each other. :) Your example would much better done with events. When you do events correctly, a widget doesn't even have to care whether there's a MainScreen at all; it just broadcasts "hey, stuff happened", and whatever has subscribed to the "stuff happened" event (be it a MainScreen, a WidgetTest, or something else entirely!) decides how it wants to respond. That's how OOP is supposed to be done anyway. :) - cHao
  • @Salvin Consider how hard it is to reason about MainScreen when debugging if it is being 'silently' updated by many components. Your example is a perfect reason why singletons are bad. - LegendLength

4

A pattern emerges when several people (or teams) arrives at similar or identical solutions. A lot of people still use singletons in their original form or using factory templates (good discussion in Alexandrescu's Modern C++ Design). Concurrency and difficulty in managing the lifetime of the object are the main obstacles, with the former easily managed as you suggest.

Like all choices, Singleton has its fair share of ups and downs. I think they can be used in moderation, especially for objects that survive the application life span. The fact that they resemble (and probably are) globals have presumably set off the purists.


4

Firstly a class and its collaborators should firstly perform their intended purpose rather than focusing on deoendents. Lifecycle management (when instances are creared snd when they go out of scope) should not be part of the cladses 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 aplication of it's usage or how it is used to configure dependents. For a quick and nasty this does not matter- just luke hardcoding 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 hardcoding a singleton.

Linked


Related

Latest