views:

5099

answers:

18

The glorified global variable - becomes a gloried global class. Some say breaking Object Oriented Design.

Give me scenarios, other than the good old logger where it makes sense to use the singleton.

+3  A: 

Managing a connection (or a pool of connections) to a database.

I would use it also to retrieve and store informations on external configuration files.

Federico Ramponi
+9  A: 

You use a singleton when you need to manage a shared resource. For instance a printer spooler. Your application should only have a single instance of the spooler in order to avoid conflicting request for the same resource.

Or a database connection or a file manager etc.

Vincent Ramdhanie
I've heard this printer spooler example and I think it's kind of lame. Who says I can't have more than one spooler? What the heck is a printer spooler anyway? What if I have different kinds of printers that can't conflict or use different drivers?
1800 INFORMATION
Its just an example...for any situation that anyone use as an example you will be able to find an alternative design that makes the example useless. Lets pretend that the spooler manages a single resource that is shared by multiple components. It works.
Vincent Ramdhanie
It's the classic example for the Gang of Four. I think an answer with a **real** tried out use case would be more useful. I mean a situation where you actually felt the Singleton is the best solution.
Andrei Vajna II
A shared resource is in my oppinion a way too broad example. How would you test that the objects using the print spooler are working correctly in the face of a malfunctioning spooler when you can't inject a malfunctioning implementation of 'spooler'? though short and uninformative the accepted answer is an a lot safer approach in my book
Rune FS
+3  A: 

One of the ways you use a singleton is to cover an instance where there must be a single "broker" controlling access to a resource. Singletons are good in loggers because they broker access to, say, a file, which can only be written to exclusively. For something like logging, they provide a way of abstracting away the writes to something like a log file -- you could wrap a caching mechanism to your singleton, etc...

Also think of a situation where you have an application with many windows/threads/etc, but which needs a single point of communication. I once used one to control jobs that I wanted my application to launch. The singleton was responsible for serializing the jobs and displaying their status to any other part of the program which was interested. In this sort of scenario, you can look at a singleton as being sort of like a "server" class running inside your application... HTH

Dave Markle
Loggers are most often Singletons so that logging objects do not have to be passed around. Any decent implementation of a log stream will ensure that concurrent writes are impossible, whether it is a Singleton or not.
metao
A: 

I use it for an object encapsulating command-line parameters when dealing with pluggable modules. The main program doesn't know what the command-line parameters are for modules that get loaded (and doesn't always even know what modules are being loaded). e.g., main loads A, which doesn't need any parameters itself (so why it should take an extra pointer / reference / whatever, I'm not sure - looks like pollution), then loads modules X, Y, and Z. Two of these, say X and Z, need (or accept) parameters, so they call back to the command-line singleton to tell it what parameters to accept, and the at runtime they call back to find out if the user actually has specified any of them.

In many ways, a singleton for handling CGI parameters would work similarly if you're only using one process per query (other mod_* methods don't do this, so it'd be bad there - thus the argument that says you shouldn't use singletons in the mod_cgi world in case you port to the mod_perl or whatever world).

Tanktalus
+4  A: 

Reading configuration files that should only be read at startup time and encapsulating them in a Singleton.

Paul Croarkin
A: 

Never use a singleton. Refactor your code.

Reference: Google testing blog

1800 INFORMATION
That's along series of articles, but interesting nonetheless.
Dusty Campbell
That's kind of blind. Can you give a coherent reason for that?
Paul Nathan
Google's C++ coding standards - http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
1800 INFORMATION
@Vlion - I pretty much agree with everything that blog link said - see especially "Singletons are pathological liars" and "Root cause of Singletons"
1800 INFORMATION
No std::cout,std::cerr, no online help? no crash handler?
Martin Beckett
That blog is long enough that this seems like a much less-useful reply than it could have been. Could you, you know, link to a relevant article?
Dean J
How the hell did this incoherent response get accepted as the answer?
Sergey
I clicked on the link, didn't see anything about singletons. That's why blog articles have permalinks.
Chance
+1  A: 

As everyone has said, a shared resource - specifically something that cannot handle concurrent access.

One specific example that I have seen, is a Lucene Search Index Writer.

Mike
+3  A: 

Read only singletons storing some global state (user language, help filepath, application path) are reasonable. Be carefull of using singletons to control business logic - single almost always ends up being multiple

Martin Beckett
+1  A: 

It can be very pragmatic to configure specific infrastructure concerns as singletons or global variables. My favourite example of this is Dependency Injection frameworks that make use of singletons to act as a connection point to the framework.

In this case you are taking a dependency on the infrastructure to simplify using the library and avoid unneeded complexity.

smaclell
+2  A: 

A Singleton candidate must satisfy three requirements:

  • controls concurrent access to a shared resource.
  • access to the resource will be requested from multiple, disparate parts of the system.
  • there can be only one object.

If your proposed Singleton has only one or two of these requirements, a redesign is almost always the correct option.

For example, a printer spooler is unlikely to be called from more than one place (the Print menu), so you can use mutexes to solve the concurrent access problem.

A simple logger is the most obvious example of a possibly-valid Singleton, but this can change with more complex logging schemes.

metao
+1  A: 

A singleton should be used when managing access to a resource which is shared by the entire application, and it would be destructive to potentially have multiple instances of the same class. Making sure that access to shared resources thread safe is one very good example of where this kind of pattern can be vital.

When using Singletons, you should make sure that you're not accidentally concealing dependencies. Ideally, the singletons (like most static variables in an application) be set up during the execution of your initialization code for the application (static void Main() for C# executables, static void main() for java executables) and then passed in to all other classes that are instantiated which require it. This helps you maintain testability.

Adam N
+40  A: 

On my quest for the truth I discovered that there are actually very few "acceptable" reasons to use a Singleton.

One reason that tends to come up over and over again on the internets is that of a "logging" class (which you mentioned). In this case, a Singleton can be used instead of a single instance of a class because a logging class usually needs to be used over and over again ad nauseam by every class in a project. If every class uses this logging class, dependency injection becomes cumbersome.

Logging is a specific example an "acceptable" Singleton because it doesn't affect the execution of your code. Disable logging, code execution remains the same. Enable it, same same. Misko puts it in the following way in Root Cause of Singletons, "The information here flows one way: From your application into the logger. Even though loggers are global state, since no information flows from loggers into your application, loggers are acceptable."

I'm sure there are other valid reasons as well. Alex Miller, in "Patterns I Hate", talks of service locators and client side UI's also being possibly "acceptable" choices.

Read more at Singleton I love you, but you're bringing me down.

CodingWithoutComments
This is the most correct answer.
seanhodges
A: 

An example with code, perhaps.

Here, the ConcreteRegistry is a singleton in a poker game that allows the behaviours all the way up the package tree access the few, core interfaces of the game (i.e., the facades for the model, view, controller, environment, etc.):

http://www.edmundkirwan.com/servlet/fractal/cs1/frac-cs40.html

Ed.

Link is now broken, but if you're registering view information in a singleton, which will be accessed throughout the application, you're missing the point of MVC. A view is updated by (and communicates to) a controller, which uses the model. As it sounds here, it's probably a misuse of Singleton and a refactoring is in order.
drharris
+1  A: 

A practical example of a singleton can be found in Test::Builder, the class which backs just about every modern Perl testing module. The Test::Builder singleton stores and brokers the state and history of the test process (historical test results, counts the number of tests run) as well as things like where the test output is going. These are all necessary to coordinate multiple testing modules, written by different authors, to work together in a single test script.

The history of Test::Builder's singleton is educational. Calling new() always gives you the same object. First, all the data was stored as class variables with nothing in the object itself. This worked until I wanted to test Test::Builder with itself. Then I needed two Test::Builder objects, one setup as a dummy, to capture and test its behavior and output, and one to be the real test object. At that point Test::Builder was refactored into a real object. The singleton object was stored as class data, and new() would always return it. create() was added to make a fresh object and enable testing.

Currently, users are wanting to change some behaviors of Test::Builder in their own module, but leave others alone, while the test history remains in common across all testing modules. What's happening now is the monolithic Test::Builder object is being broken down into smaller pieces (history, output, format...) with a Test::Builder instance collecting them together. Now Test::Builder no longer has to be a singleton. Its components, like history, can be. This pushes the inflexible necessity of a singleton down a level. It gives more flexibility to the user to mix-and-match pieces. The smaller singleton objects can now just store data, with their containing objects deciding how to use it. It even allows a non-Test::Builder class to play along by using the Test::Builder history and output singletons.

Seems to be there's a push and pull between coordination of data and flexibility of behavior which can be mitigated by putting the singleton around just shared data with the smallest amount of behavior as possible to ensure data integrity.

Schwern
A: 

1 - A comment on the first answer:

I don't agree with a static Logger class. this can be practical for an implementation, but it cannot be replaceable for unit testing. A static class cannot be replaced by a test double. If you don't unit test, you won't don't see the problem here.

2 - I try not to create a singleton by hand. I just create a simple object with constructors that allow me to inject collaborators into the object. If I needed a singleton, I'd use a dependency inyection framework (Spring.NET, Unity for .NET, Spring for Java), or some other.

bloparod
You should comment on answers directly by clicking on the link at the bottom of an answer; it's much easier to read that way. Also, the answer you saw at the top probably isn't the first. Answers get reordered all the time.
Ross
A: 

When you load a configuration Properties object, either from the database or a file, it helps to have it as a singleton; there's no reason to keep re-reading static data that won't change while the server is running.

Dean J
A: 

You can use Singleton when implementing the State pattern (in the manner shown in the GoF book). This is because the concrete State classes have no state of their own, and perform their actions in terms of a context class.

You can also make Abstract Factory a singleton.

Emile Cormier