views:

445

answers:

12

Possible Duplicate:
On Design Patterns: When to use the Singleton?

This question is not about whether or not singletons are "considered harmful" in general. I just want to know, from your experience, what are some SPECIFIC SITUATIONS in which singletons seem to work well.

EDIT: Please, if you want to discuss the appropriateness and/or evilness of singletons in general, there are aleady exising questions: 137975, 11831

Oops! I've just discovered that my question has already been asked here: http://stackoverflow.com/questions/228164/on-design-patterns-when-to-use-the-singleton

+1  A: 

There is a single device/hardware attached to the system and a central point of control is necessary in order to use it properly.

Szere Dyeri
I've seen some "premature singletonization" in embedded systems where the driver for a communications port would only support one instance. Later, when more comm ports became available, the driver needed to be overhauled to support multiple instances. Parts of the application code using the comm port driver also needed some rewriting. I wonder, what device would always truly be unique and never have multiple instances?
Emile Cormier
I would also say not to use a singleton for hardware. Otherwise you can't test your code separately from the hardware. Best to create an interface.I can see a singleton being useful if you need to write to the hardware from many different places in your code, but it seems to me that would be poor design.
Mike Weller
A: 

I just worked really hard getting rid of Singletons in the current project I am working on. They have a smell, but sometimes are very difficult to avoid.

My situation was that I had an API which constructed singleton objects for handling management functions such as Security, Configuration, etc. The API used EntityFramework and also pulled in PlugIns (using MEF). Because the construction of these classes was not always performed by my code (particularly for EF entities), it was not always possible to inject these into biz objects elegantly. So I used singletons, which can be accessed anywhere within a project subject tot heir scope.

Program.X
A: 

They're good for items that you wish to consider as unique resources.

As an example in web systems you may wish to only use a single database connection for each page that's served - in this instance using the singleton pattern would make sense. (Although you'd have to code with the knowledge that the database access object was a singleton, which is less ideal, but acceptable if clearly documented, etc.)

middaparka
+6  A: 

We basically use them for two things: logging, and configuration. Both assume that the app has a central config and a central logfile, not always valid but in most of our code it is. We also use them on occasion for certain factory classes or cache classes we want to make sure we're not duplicating key metadata.

Joe
A: 

When a part of your program needs an object that implements a specific interface (polymorphism-wise), but you never want more than a single instance of that object. Otherwise static methods will do.

Cecil Has a Name
A: 

Master server takes requests from clients, and passes these requests off to a subordinate process. The subordinate process may use a singleton for communicating with the master server.

Aidan Cully
Uncommented downvotes are really annoying. I describe a pattern used in Postfix - the Postfix master server manages the connection paths between all the other executables in the system. If one sub-part of the system needs to talk to another, it needs to use the master server to find out how.
Aidan Cully
(the downvote's not mine) you can run multiple Postfix instances on a single machine => the master is not a Singleton. plus it would not be a valid reason to use the pattern in the implementation of the subordinate, IMO.
just somebody
The master is not a singleton, and I don't think I describe it as such. Each individual subordinate process has a singleton connection to the specific master that controls it. It does not make sense for a subordinate to have multiple masters.
Aidan Cully
ok, but what problem is being solved by using the Singleton DP in the subordinate?
just somebody
I see your point... There are possible answers - encoding explicitly that the subordinate should not have multiple masters, or enforcing the process-separation that is a fundamental part of Postfix's security model (in which some of the drawbacks of singletons (hampering same-address-space code refactoring) are turned into benefits, since it may be a design goal to enforce process separation) - but nothing that seems really compelling to me.
Aidan Cully
A: 

I try not to rely on Singleton, however I prefer decoupling to not using Singleton. Thus, I often use Singleton coupled with the Prototype pattern, which allow for registering the Prototypes at library load (global objects construction).

I am writing a server consisting of a number of libraries. There is a number of "common" libraries, then one library per service. A "main" library is tasked with the purpose of looking at the message received and invoked the right service depending on a key... This uses a simple std::map.

Using a Singleton for the map allow me to have totally decoupled code. No library depends on my service library, no line of code outside my service library is tasked with registering its service. In fact, it is such that I can decide which services are embedded simply by altering my "link" command at compile-time: if I do not link with a library, its service is not embedded.

I really find it useful there... for configuration and such I prefer to use the MonoPattern: ie normal looking class with all instances sharing the same data (thus wrapping a real singleton). Makes for easier migration just in case it's necesary since the clients don't know they are using a Singleton undercover.

Matthieu M.
+1  A: 
  • Logging.

  • Finding localized string resources e.g. Strings.get("CONFIRM_DELETE").

Both of these things are not details that should be exposed in the public interface of your objects, so it makes sense to use a singleton here.

Mike Weller
I disagree about the second, at least in some applications. What if you want to support multiple languages at once?
Aidan Cully
What do you mean at once? Strings.get("foo") will retrieve the correct string from a properties file based on the current language. Change the language, restart the program and you get the new language strings.
Mike Weller
If you're a network server handling connections from all over the world, you may send strings to one client in one language, and to another client in another language.
Aidan Cully
Questioning the resource lookup thing... I'm currently seeing a singleton lookup of localised Strings becoming a bit of a pain for unit testing (in Java). A single lookup turns a <0.1s test into a 3s test. I can see this mounting up. Whereas if the thing that did the lookup was injected, I could fake it out to not be a performance problem.
Grundlefleck
Playing devil's advocate here... How about TheStrings.get(language, "CONFIRM_DELETE")?
Emile Cormier
A: 

In addition to logging (as most others have already mentioned), I've used singletons for Inversion of Control (IoC) Containers. The dependencies are registered once at the start of the application, and one can resolve a dependency at any point in time during the app using the singleton method.

Secret Agent Man
Is this similar to what is also known as the Service Locator pattern, or am I mixing my patterns? :)
Grundlefleck
+6  A: 

Expanding my comment...

The question is poorly worded, singletons seem to work well in many situations. It should be "what are some specific situations in which singletons don't expose their negative properties?" Briefly, "when are global variables good"?

  1. A global variable is a global variable.

    As soon as you use

    void f() { X* x = X::getInstance(); ... }

    instead of void f(X*), your order for the spaghetti dish has been accepted.

  2. Singletons proliferate, and like to depend on each other. SessionManager uses EventManager which uses LogManager. Someone wants the log files to mention the name of the current user. The LogManager maintainer adds SessionManager::getInstance()->getUser()->getName();, everything's roses until the LoginManager, which also uses LogManager, wants to log a login failure.

  3. Singletons inhibit testability.

    The single-instance property is semi-useful only in production code. You may be unable to test the void f() function at all, and probably will have (few) tests only for the happy path.

As you can guess, my answer to when are global variables good? is "never". What is yours?

just somebody
*"...when are global variables good?"* Are you asking me? So far, I'd use singletons (call them globals if you want) when dependency injection would be a total PITA (a greater PITA than the problems globals give you with unit testing). For example, I can't imagine passing a logging object to every one of my classes.
Emile Cormier
-1 For not answering my question, sorry (I don't disagree with your viewpoint, however). I wanted to know what are **specific situations** where singletons (call them globals if you want) work well.
Emile Cormier
i am hard-pressed to believe that *every one of your classes* has any business logging its operations. unless you use logging as a substitute for a debugger. anyway, in the cases where I've encountered this objection, the (perceived or real) was induced by spaghetti code. after refactoring, the previously-singletons were passed where needed, which turned out to be very manageable extent.
just somebody
I was very specific in the answer: never.
just somebody
Your answer went against the spirit of my question. You used my question as a soapbox for your anti-singleton views.
Emile Cormier
Going back to the logger thing, there was one case where the logger was "abused" for debugging purposes and it served me well. The software was run in an real-time environment that was difficult to duplicate at the office, so it was important to log minute details in a special "debug" category. If I were to do it all over again, I'd probably go though the excise of injecting the logger just to see how much of a PITA it really is.
Emile Cormier
Ok, what should I do differently (without changing the meaning of the answer) to meet your criteria?
just somebody
re logger: I've seen a singleton/global logger used within a `String` class. I agree that it's *very* inconvenient to pass a logger to the constructor of every instance of such a class. But I also think such a class has no business in logging. There's a dichotomy IMO: either an object should log, and then it's a major thing (implies there is few of such objects, near the root of the object graph), or it's a small critter, there's bazillion of them in the lower layers, but they are too small and dumb to log anything interesting.
just somebody
Hmmm.... Now that I think about it, it's good to "question the question" and think outside the box. I've done it myself, and it's not fair for me to say you can't do it here. Sorry for being a hypocrite. :-) Just touch your answer, and I'll undo my -1. Besides, your answer is a good placeholder for others who also want to answer "never".
Emile Cormier
Ok, done, and thank you. Though I should mention that I don't see my answer as "questioning the question". Rather, I'm just saying that the set of specific situations you ask about is empty.
just somebody
A: 
  • When your domain specifies that there only exists one unique instance of something you're modelling

I still believe singletons should be avoided (in Java at least).

There's two different things to consider: the concept and the mechanism for enforcing the Singleton pattern.

The concept of Singletons have many uses, logging, configuration, not to mention when the domain you're working actually has things where there is ever only one instance of them and you wish to model that. I.e. a company only has a single expenses processing office and sending expense forms to an invalid office is wrong, the office is in reality a singleton. The concept of a singleton has many legitimate uses.

However, it's usually the mechanism that causes the problem. In Java we enforce an object can't be constructed by declaring the constructor private, the problem with this is we also have to provide a global point of access to the instance through the concrete class. This couples everything in your application to that concrete class, which can't be changed at run-time, or mocked in unit testing. It's this mechanism which is considered evil - particularly in terms of testability.

If the concept of Singletons can be separated from the poor mechanisms, they would not be so evil. One example, I can think of is the @Singleton scope available in Guice. In the context of Guice, it guarantees one instance, but it doesn't achieve this with the evil private constructor/global point of access mechanism.

Grundlefleck
+1  A: 

Generating a sequence of random numbers - the random generator should be unique, not instantiated for each use. One might want to implement this as a thread-level singleton; however, a singleton for the whole process is still appropriate in this case.

lmsasu