views:

4186

answers:

24

Singletons are a hotly debated design pattern, so I am interested in what the Stack Overflow community thought about them.

Please provide reasons for your opinions, not just "Singletons are for lazy programmers!"

Here is a fairly good article on the issue, although it is against the use of Singletons: scientificninja.com: performant-singletons.

Does anyone have any other good articles on them? Maybe in support of Singletons?

+20  A: 

The purpose of a Singleton is to ensure a class has only one instance, and provide a global point of access to it. Most of the time the focus is on the single instance point. Imagine if it were called a Globalton. It would sound less appealing as this emphasizes the (usually) negative connotations of a global variable.

Most of the good arguments against singletons have to do with the difficulty they present in testing as creating test doubles for them is not easy.

dpp
So why should a class ensure itself that it only has one instance? This pretty much defeats the purposes of object-oriented programming.
Patrick Daryll Glandien
Usually you'd want only one logging facility? Or you're wrapping some voodoo dll, and you don't want to make it possible to load the dll twice?
Calyth
@Calyth but _why_ make that as responsibility of the class it self when it is clearly as system responsibility. (any one instance of the object will work just fine but the system might fail if the only one alive at a time constraint is not met)
Rune FS
+1  A: 

Singletons have their uses, but one must be careful in using and exposing them, because they are way too easy to abuse, difficult to truly unit test, and it is easy to create circular dependencies based on two singletons that accesses each other.

It is helpful however, for when you want to be sure that all your data is synchronized across multiple instances, e.g., configurations for a distributed application, for instance, may rely on singletons to make sure that all connections use the same up-to-date set of data.

Jon Limjap
+24  A: 

A singleton is just a bunch of global variables in a fancy dress.

Global variables have their uses, as do singletons, but if you think you're doing something cool and useful with a singleton instead of using a yucky global variable (everyone knows globals are bad mmkay), you're unfortunately misled.

Orion Edwards
+32  A: 

Google has a Singleton Detector for Java that I believe started out as a tool that must be run on all code produced at Google. The nutshell reason to remove Singletons:

because they can make testing difficult and hide problems with your design

For a more explicit explanation see 'Why Singletons Are Controversial' from Google.

Brian
I suspect it's a stretch to say this 'must be run on all code produced at Google.' (For one thing, they probably use other languages.)
Tyler
I believe Java, Python and C++ are the approved languages at google.
Brian
They can also use javascript: http://steve-yegge.blogspot.com/2007/06/rhino-on-rails.html
CTT
Google also has an accounting department; does that mean every developer should get one? The decision to disallow certain constructs is a business decision on Google's part that speaks more to their internal environment. No doubt some hand-tuned machine code still gets twiddled with there, but for business reasons not just anybody should be doing so.
Dustman
Go and read some Google code, they do *not* live by this rule.
jkp
+1  A: 

I find you have to be very careful about why you're deciding to use a singleton. As others have mentioned, it's essentially the same issue as using global variables. You must be very cautious and consider what you could be doing by using one.

It's very rare to use them and usually there is a better way to do things. I've run into situations where I've done something with a singleton and then had to sift through my code to take it out after I discovered how much worse it made things (or after I came up with a much better, more sane solution)

Dan Herbert
+5  A: 

I've been trying to think of a way to come to the poor singelton's rescue here, but I must admit it's hard. I've seen very few legitimate uses of them and with the current drive to do dependency injection andd unit testing they are just hard to use. They definetly are the "cargo cult" manifestation of programming with design patterns I have worked with many programmers that have never cracked the "GoF" book but they know 'Singelton' and thus they know 'Patterns'.

I do have to disagree with Orion though, most of the time I've seen singeltons oversused it's not global variables in a dress, but more like global services(methods) in a dress. It's interesting to note that if you try to use Singeltons in the SQL Server 2005 in safe mode through the CLR interface the system will flag the code. The problem is that you have persistent data beyond any given transaction that may run, of course if you make the instance variable read only you can get around the issue.

That issue lead to a lot of rework for me one year.

Dan Blair
I never understood why people 'love' this pattern so much. I guess it's because it 'allows' you to use global variables, which saves you the trouble of rethinking the design. Except, of course, it doesn't.
Chris Huang-Leaver
A: 

I really disagree on the bunch of global variables in a fancy dress idea. Singletons are really useful when used to solve the right problem. Let me give you a real example.

I once developed a small piece of software to a place I worked, and some forms had to use some info about the company, its employees, services and prices. At its first version, the system kept loading that data from the database every time a form was opened. Of course, I soon realized this approach was not the best one.

Then I created a singleton class, named company, which encapsulated everything about the place, and it was completely filled with data by the time the system was opened.

It was not just a bunch of variables in a fancy dress because this was had dozens of responsibilities, like communicating with persistence layer to save/retrieve data about the company, deal with employees and prices collections, etc.

Plus, it was a fixed, system-wide, easily accessible point to have the company data.

Mario Marinato -br-
I didn't down-vote this, but I would like to explain why someone might have down-voted.Singlton is not the best/only way to cache data.A class with dozens of responsibilities is not "properly" designed.
David B
Here here David B.
Dave
It sounds like your singleton should have been a separate program entirely. The interface is its service layer.
Gary
+2  A: 

It was not just a bunch of variables in a fancy dress because this was had dozens of responsibilities, like communicating with persistence layer to save/retrieve data about the company, deal with employees and prices collections, etc.

I must say you're not really describing somthing that should be a single object and it's debatable that any of them, other than Data Serialization should have been a singelton.

I can see at least 3 sets of classes that I would normally design in, but I tend to favor smaller simpler objects that do a narrow set of tasks very well. I know that this is not the nature of most programmers. (Yes I work on 5000 line class monstrosities every day, and I have a special love for the 1200 line methods some people write.)

I think the point is that in most cases you don't need a singelton and often your just making your life harder.

Dan Blair
+4  A: 

Holy wars! Ok let me see.. Last time I checked the design police said..

Singletons are bad because they hinder auto testing - instances cannot be created afresh for each test case. Instead the logic should be in a class (A) that can be easily instantiated and tested. Another class (B) should be responsible for constraining creation. Single Responsibility Principle to the fore! It should be team-knowledge that you're supposed to go via B to access A - sort of a team convention.

I concur mostly..

Gishu
+6  A: 

I think there is a great misunderstanding about the use of the Singleton pattern. Most of the comments here refer to it as a place to access global data. We need to be careful here - Singleton as a pattern is not for accessing globals.

Singleton should be used to have only one instance of the given class. Pattern Repository has great information on Singleton.

Cem Catikkas
+1  A: 

I've used singletons a bunch of times in conjunction with Spring and didn't consider it a crutch or lazy.

What this pattern allowed me to do was create a single class for a bunch of configuration-type values and then share the single (non-mutable) instance of that specific configuration instance between several users of my web application.

In my case, the singleton contained client configuration criteria - css file location, db connection criteria, feature sets, etc. - specific for that client. These classes were instantiated and accessed through Spring and shared by users with the same configuration (i.e. 2 users from the same company). * *I know there's a name for this type of application but it's escaping me

I feel it would've been wasteful to create (then garbage collect) new instances of these "constant" objects for each user of the app.

Vinnie
that's an ok way to do it. The problems come with static accessors for singletons.
Gary
A: 

Singletons are very useful, and using them is not in and of itself an anti-pattern. However, they've gotten a bad reputation largely because they force any consuming code to acknowledge that they are a singleton in order to interact with them. That means if you ever need to "un-Singletonize" them, the impact on your codebase can be very significant.

Instead, I'd suggest either hiding the Singleton behind a factory. That way, if you need to alter the service's instantiation behavior in the future, you can just change the factory rather than all types that consume the Singleton.

Even better, use an inversion of control container! Most of them allow you to separate instantiation behavior from the implementation of your classes.

Nate Kohari
+33  A: 

In defense of singletons:

  • They are not as bad as globals because globals have no standard-enforced initialization order, and you could easily see nondeterministic bugs due to naive or unexpected dependency orders. Singletons (assuming they're allocated on the heap) are created after all globals, and in a very predictable place in the code.
  • They're very useful for resource-lazy / -caching systems such as an interface to a slow I/O device. If you intelligently build a singleton interface to a slow device, and no one ever calls it, you won't waste any time. If another piece of code calls it from multiple places, your singleton can optimize caching for both simultaneously, and avoid any double look-ups. You can also easily avoid any deadlock condition on the singleton-controlled resource.

Against singletons:

  • In C++, there's no nice way to auto-clean-up after singletons. There are work-arounds, and slightly hacky ways to do it, but there's just no simple, universal way to make sure your singleton's destructor is always called. This isn't so terrible memory-wise -- just think of it as more global variables, for this purpose. But it can be bad if your singleton allocates other resources (e.g. locks some files) and doesn't release them.

My own opinion:

I use singletons, but avoid them if there's a reasonable alternative. This has worked well for me so far, and I have found them to be testable, although slightly more work to test.

Tyler
Any reason for the down vote?
Tyler
I totally agree with your second reasoning
Malfist
The assumption in the first point is quite a leap, usually heap allocation is not how singletons are created (in C++ at least).
MadKeithV
I'm not sure about that, MadKeithV. There's a standard pattern where a member function, say, MyClass* MyClass::get_instance(), checks a static member pointer, and if it's NULL calls new to allocate (on the heap) the shared instance. How would a singleton live elsewhere?
Tyler
+19  A: 

There's three pretty good blog posts about Singletons by Miško Hevery in the Google Testing blog.

  1. Singletons are Pathological Liars
  2. Where Have All the Singletons Gone?
  3. Root Cause of Singletons
Bleadof
woow, really interesting stuff, but i want solutions! :-) txn
Sander Versluys
I think one of the "solutions" is dependency injection which actually handles the instance injection for you and it reliefs singleton from being a anti-pattern. :) Check out Guice! http://code.google.com/p/google-guice/
Bleadof
+2  A: 

The biggest problem with singletons is that they make unit testing hard, particularly when you want to run your tests in parallel but independently.

The second is that people often believe that lazy initialisation with double-checked locking is a good way to implement them.

Finally, unless your singletons are immutable, then they can easily become a performance problem when you try and scale your application up to run in multiple threads on multiple processors. Contended synchronization is expensive in most environments.

Bill Michell
Anyone care to share the reason for the down-votes?
Bill Michell
Bill, I have to say I wonder too? I don't have much experience, but your point about concurrency issues sounds logical to me?
Glytzhkof
What is wrong with using singletons in lazy initialization, where the singleton is a helper for example? I'm not saying you're wrong, I'm just asking.
Flavius
The problem is in using double-checked locking to initialise them. See http://en.wikipedia.org/wiki/Double-checked_locking - in Java, for example, the simple double-checked implementation is not thread safe and so may cause difficult-to-diagnose failures.
Bill Michell
A: 

One scary thing on singletons in for instance Java is that you can end up with multiple instances of the same singleton in some cases. The JVM uniquely identifies based on two elements: A class' fully qualified name, and the classloader responsible for loading it.

That means the same class can be loaded by two classloaders unaware of each other, and different parts of your application would have different instances of this singleton that they interact with.

Asgeir S. Nilsen
If the same class is loaded by two class loaders it's not the same class.
Tom Hawtin - tackline
If the class is loaded by classloaders A and B, but they both implement the same interface loaded by classloader C, then you can pass instances of the class from classloaders A and B to users of C. So the program can use two instances of a singleton at the same time.
Esko Luontola
+4  A: 

One of the colleagues I have worked with was very Singleton-minded. Whenever there was something that was kind of a manager or boss like object he would make that into a singleton, because he figured that there should be only one boss. And each time the system took up some new requirements, it turned out there were perfectly valid reasons to allow multiple instances.

I would say that singleton should be used if the domain model dictates (not 'suggests') that there is one. All other cases are just accendentally single instances of a class.

andreas buykx
Woo hoo! Pragmatism! I like!
Dustman
A: 

Write normal, testable, injectable objects and let Guice/Spring/whatever handle the instantiation. Seriously.

This applies even in the case of caches or whatever the natural use cases for singletons are. There's no need to repeat the horror of writing code to try to enforce one instance. Let your dependency injection framework handle it. (I recommend Guice for a lightweight DI container if you're not already using one).

Ben Hardy
+2  A: 

Singleton as an implementation detail is fine. Singleton as an interface or as an access mechanism is a giant PITA.

A static method that takes no parameters returning an instance of an object is only slightly different from just using a global variable. If instead an object has a reference to the singleton object passed in, either via constructor or other method, then it doesn't matter how the singleton is actually created and the whole pattern turns out not to matter.

MSN
+3  A: 

Many applications require that there is only one instance of some class, so the pattern of having only one instance of a class is useful. But there are variations to how the pattern is implemented.

There is the static singleton, in which the class forces that there can only be one instance of the class per process (in Java actually one per ClassLoader). Another option is to create only one instance.

Static singletons are evil - one sort of global variables. They make testing harder, because it's not possible to execute the tests in full isolation. You need complicated setup and tear down code for cleaning the system between every test, and it's very easy to forget to clean some global state properly, which in turn may result in unspecified behaviour in tests.

Creating only one instance is good. You just create one instance when the programs starts, and then pass the pointer to that instance to all other objects which need it. Dependency injection frameworks make this easy - you just configure the scope of the object, and the DI framework will take care of creating the instance and passing it to all who need it. For example in Guice you would annotate the class with @Singleton, and the DI framework will create only one instance of the class (per application - you can have multiple applications running in the same JVM). This makes testing easy, because you can create a new instance of the class for each test, and let the garbage collector destroy the instance when it is no more used. No global state will leak from one test to another.

For more information: The Clean Code Talks - "Global State and Singletons"

Esko Luontola
With regard to the cleaning of such objects between tests, why need it be complicated? Why can't the object be destroyed, and a new one spun up in it's place? Having no facility for this is an implementation issue, not a problem with the Pattern itself.
Dustman
The problem is *remembering* to always clean the objects after a test. Also since the code may get access to a static singleton from anywhere, it's not possible to see just by looking at the test code, whether some class uses a static singleton, so it's very easy to forget some dependencies. Compare this to dependency injection, where all dependencies must be declared explicitly in the constructor - the code will not even compile if some dependency is forgotten.
Esko Luontola
A: 

It seems to me that Singletons are considered bad only because it's hard to test them with current testing tools. Perhaps that's a limitation of the current testing tools and not the pattern itself.

Any good thing can be abused. Most of the arguments I hear is that singletons are ssentially global variables. They're not.

What makes a global variable bad is that they are in scope despite being out of the visible scope, so it's way too easy to accidentally use them or accidentally not use them. It's virtually impossible to "accidentally" use a singleton variable. It's very format makes its use quite deliberate.

There is certainly some argument that singletons can obscure the call graph, because it allows calling objects across layers, but you can achieve the same thing by passing an object down the graph via parameters.

What's worse, the suggested "fixes" for singletons, such as singleton factories, don't change any of those problems, they just shuffle it around, and worse... they make it possible to instantiate multiple singletons.

Mystere Man
Singletons are global state, period.
Chad Grant
there's much more to it than that... watch the google videos about it. Although I agree singleton factories are useless if you have to use a global accessor to get to them. Globals are bad.
Gary
+9  A: 

Singleton is not a horrible pattern, although it is misused a lot. I think this misuse is because it is one of the easier patterns and most new to the singleton are attracted to the global side effect.

Erich Gamma had said the singleton is a pattern he wishes wasn't included in the GOF book and it's a bad design. I tend to disagree.

If the pattern is used in order to create a single instance of an object at any given time then the pattern is being used correctly. If the singleton is used in order to give a global effect, it is being used incorrectly.

Disadvantages:

  • You are coupling to one class throughout the code that calls the singleton
    • Creates a hassle with unit testing because it is difficult to replace the instance with a mock object
    • If the code needs to be refactored later on because of the need for more than one instance, it is more painful than if the singleton class were passed into the object (using an interface) that uses it

Advantages:

  • One instance of a class is represented at any given point in time.
    • By design you are enforcing this
  • Instance is created when it is needed
  • Global access is a side effect
Chap
"Global access is a side effect" I'm glad someone pointed this out. The global aspect is probably the most misused part of a singleton
RobS
I bet Eric Gamma's opinion on singletons came from a lot of hard-earned experience.
Gary
+2  A: 

Chicks dig me because I rarely use singleton and when I do it's typically something unusual. No, seriously, I love the singleton pattern. You know why? Because:

  1. I'm lazy.
  2. Nothing can go wrong.

Sure, the "experts" will throw around a bunch of talk about "unit testing" and "dependency injection" but that's all a load of dingo's kidneys. You say the singleton is hard to unit test? No problem! Just declare everything public and turn your class into a fun house of global goodness. You remember the show Highlander from the 1990's? The singleton is kind of like that because: A. It can never die; and B. There can be only one. So stop listening to all those DI weenies and implement your singleton with abandon. Here are some more good reasons...

  • Everybody is doing it.
  • The singleton pattern makes you invincible.
  • Singleton rhymes with "win" (or "fun" depending on your accent).
Repo Man
+1 for lol factor
Gary
+2  A: 

I'm reading a lot about "Singleton", its problems, when to use it, etc., and these are my conclusions until now:

  • Confusion between the classic implementation of Singleton and the real requirement: TO HAVE JUST ONE INSTANCE OF a CLASS!

  • It's generally bad implemented. If you want a unique instance, don't use the (anti)pattern of using a static GetInstance() method returning a static object. This makes a class to be responsible for instantiating a single instance of itself and also perform logic. This breaks the Single Responsibility Principle. Instead, this should be implemented by a factory class with the responsibility of ensuring that only one instance exists.

  • It's used in constructors, because it's easy to use and must not be passed as a parameter. This should be resolved using dependency injection, that is a great pattern to achieve a good and testable object model.

  • Not TDD. If you do TDD, dependencies are extracted from the implementation because you want your tests to be easy to write. This makes your object model to be better. If you use TDD, you won't write a static GetInstance =). BTW, if you think in objects with clear responsibilities instead classes, you'll get the same effect =).

bloparod