110

Possible Duplicate:
What is so bad about Singletons?

Singleton Design Pattern: Pitfalls

Singleton anti-pattern

I've heard recently that Singleton is an anti-pattern. I know it has to do with the fact making a class singleton is like making that unique instance a global variable, but it's also doing a lot more than that (limiting the number of instances of that object, managing instantiation, etc..).

Why exactly is Singleton considered an anti-pattern? And what are the alternatives?

Community
  • 1
  • 1
user1710031
  • 1,181
  • 3
  • 9
  • 7
  • 2
    I know Singleton is overused - I've seen people use it in instances where it should not have been used - but it was the first time I heard it referred as an anti-pattern. Since then, I've been googling a little bit and found out quite some people consider it to be an anti-pattern, but I haven't found any acceptable explanation... Dour High Arch: Just google "singleton anti pattern" and you'll find hundreds of articles about it... But I can't find any that really justifies it. Which is why I am asking here. – user1710031 Oct 06 '12 at 00:13
  • 1
    Dour High Arch: No duplicate. I did find that post. But it doesn't answer: "Why exactly is Singleton considered an anti-pattern? And what are the alternatives?" PS: GG deleting your previous comment. – user1710031 Oct 06 '12 at 00:15
  • Nice link: http://www.ibm.com/developerworks/webservices/library/co-single/index.html – assylias Oct 06 '12 at 00:20
  • If you look at Dour's link, in the comments there is another link to a [blog post](http://jalf.dk/blog/2010/03/singletons-solving-problems-you-didnt-know-you-never-had-since-1995/) which does answer the first part of the question pretty well. Also, as for alternatives, the other SO post discusses DI (Dependency Injection). If that doesn't answer your two questions, could you elaborate what you're looking for? – WeirdlyCheezy Oct 06 '12 at 00:25
  • See my answer here: http://www.michaelsafyan.com/tech/design/patterns/singleton – Michael Aaron Safyan Aug 13 '15 at 04:49
  • I'm seeing a mixture of answers, for example, one article gives reasons why they hate the pattern, then later in the same article, they give some reasonable situations! Singleton has some glaring misuses, people need to be very cautious before reaching for it. Exercising caution (perhaps more than other patterns) doesn't mean it's a bad pattern. It has its uses, rare they may be; doesn't make it an anti-pattern. – dan Apr 12 '23 at 20:10

4 Answers4

103

To help with answering, here is more about the anti-pattern comment:

it is overused, introduces unnecessary restrictions in situations where a sole instance of a class is not actually required, and introduces global state into an application

From: http://en.wikipedia.org/wiki/Singleton_pattern

For more on this you can look at: https://www.michaelsafyan.com/tech/design/patterns/singleton

Here is a great ending to the blog above:

In short, the singleton pattern makes code more complex, less useful, and a real pain to re-use or test. Eliminating singletons can be tricky, but it’s a worthwhile endeavour.

OK, so, the reason it is an anti-pattern is described well in this paragraph, and, as the author expresses, it tightly couples your code to the singleton.

If you find that you want to use a singleton, you may want to consider your design, but there are times where it is useful.

For example, once I had to write an application that could have at most one database connection, to process thousands of requests. So, a singleton makes sense since I am resource constrained to having only one instance.

But, generally this is used to simplify code, without thinking of the difficulties that will be introduced.

For example, and this applies to static classes also, if you unit test, or have concurrency, then the state of one request will change the state and that may cause problems, as the class calling the instance may be assuming the state is as it expected.

I think the best way to challenge the use is to think of how to handle it if your program is multi-threaded, and a simple way to do that is to unit test it, if you have several tests that run at one time.

If you find that you still need it, then use it, but realize the problems that will be encountered later.

James Black
  • 41,583
  • 10
  • 86
  • 166
  • 9
    Good answer. Just wanted to add though that even your DB example should be solved w/o a singleton. Easiest solution, w/o knowing the exact use case obviously, would be to have a factory which returns the single instance. It's a more elegant approach and doesn't violate SRP (as the Singleton pattern does). Also if the situation changes and your application needs to be modified to allow for multiple DB connections it will be a breeze to refactor compared to a singleton. There literally is no situation in which a singleton is preferable to another pattern. – Creynders Oct 08 '12 at 07:29
  • 2
    @Creynders - Actually my problem was solved by having a separate program that ran, that just looked in a queue and processed what it found, so it had just one connection, but, a Singleton may have been a good fit there. I have had similar issues where I may have just 5 connections allowed, and something similar to the Singleton may work, as it would basically be a Factory that functions similar to a Singleton. – James Black Oct 08 '12 at 12:41
  • The artical of Michael Safyan above is the best one I have found for singleton – camino Jul 13 '17 at 17:47
  • 2
    The database is great example of antipattern - build whole program logic around current performance assumptions. – kwesolowski Jan 03 '18 at 12:32
  • Having a constraint to use one database is not a good reason to use singleton. This is like having a requirement to output one line of text, so you add code to insure that print is called only once. There is however a good use: You have a broken classes, than has hard-coded assumptions about a single resource (instead of excepting a db via constructor, and using a factory). The class will take time to fix, and for now you only need one instance. Therefore make it a singleton, not to indicate that we want only one instance, but to indicate that it is limited to one instance. – ctrl-alt-delor Mar 02 '18 at 23:21
  • @ctrl-alt-delor But doesn't this clash with dependency injection, where you'd normally register a single dependency to a single instance. Frameworks like Angular is solely structured around that fact. Still they've managed to make it easily testable. – DarkNeuron Jun 06 '19 at 11:28
  • @DarkNeuron Singleton is a type of factory pattern, but it also has a restriction of one instance. Just use one or more of the other factory patterns. – ctrl-alt-delor Jun 06 '19 at 11:52
  • @ctrl-alt-delor But my question was about dependency injection, which inherently uses singletons. – DarkNeuron Jun 06 '19 at 12:13
  • @DarkNeuron I have never used singleton to do my dependency injection. – ctrl-alt-delor Jun 06 '19 at 12:55
  • @ctrl-alt-delor Sorry, you had to read my mind in order to know I really meant IOC containers, like the one Angular provides. Whoops :-) – DarkNeuron Jun 07 '19 at 15:49
  • @DarkNeuron does it insist on singleton? – ctrl-alt-delor Jun 07 '19 at 16:08
  • @ctrl-alt-delor It does. In case you're not familiar with Angular, all services/providers are singletons. They instantiated once, and then Angular's IOC container will inject that instance automatically whenever you define that service class as a constructor parameter somewhere. I can see with this goes against OO principles, which makes me wonder why they chose that approach. I'm sure there are ways around it, but it is the default behavior. – DarkNeuron Jun 10 '19 at 08:14
  • I think this: "introduces global state into an application" is more about Java application static context not singleton itself. – chill appreciator Jun 15 '20 at 16:28
35

I wouldn't exactly consider singleton to be an anti-pattern.

However, a singleton is basically a way to use global variables. And global variables are bad because any code anywhere in the system can change their values. So when debugging, it can be challenging to figure out which code path leads to the Singleton's current state.

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
Jack Edmonds
  • 31,931
  • 18
  • 65
  • 77
  • 11
    False. Global variables can't be changed if they are hidden. – Andrew May 01 '17 at 15:53
  • 1
    I never heard of "hidden" in terms of C++ standard, can you elaborate? – Joky Jul 10 '17 at 19:46
  • @Joky I assume that hidden = abstracted. – ctrl-alt-delor Mar 02 '18 at 23:23
  • 2
    This is not the reason. Singleton does 3 things (violation of single responsibility principle): It does its main responsibility, it is a factory (see factory pattern), it insures a single instance (this is a bad idea, unless it is a temporary measure, to mark a class as in need of repeat, so that there can be more than one instance). – ctrl-alt-delor Mar 02 '18 at 23:26
  • What about singletons without sate, which should be the case for all singleton of course. – Tristan Sep 01 '20 at 12:41
  • @Tristan why use a object if it has no state? You could just use static functions. – YAMM Jul 09 '22 at 15:39
  • These reasons, to begin with : https://practice.geeksforgeeks.org/problems/what-are-the-limitations-of-static-method-in-java – Tristan Jul 10 '22 at 07:02
10

Singletons are often badly implemented. See double-checked-locking.

In which scope must an Singleton instance be unique. Like multi-Threaded environments, clustering etc.

Singletons can be hard to test.

Memory allocated to an Singleton can't be freed.

With excessiv usage of singletons you leave from objectoriented programming to procedural programming.

daniel
  • 3,166
  • 2
  • 17
  • 18
  • 17
    "Memory allocated to an Singleton can't be freed." Maybe that memory doesn't need to be freed, and that's why it was put in the Singleton? Plus, it can free the memory itself if it needs to. – Andrew May 01 '17 at 15:55
10

I think it is considered an anti-pattern because a Singleton class can't be instantiated in a normal way by other object (except by calling such method commonly named "getInstance"). So, it will look like the class is being used directly without instantiating it to create a usable object first.

I agree with you that Singleton can serve as a global unique instance. I learned from some people that as alternatives for Singleton, we can use static and/or final variables, and we can also use enumeration (so that we can group multiple variables under one group name as what we usually do when we are working using a normal class/object).

However, these alternatives can only match the capability of a Singleton class in storing states/values. If we need unique functions to work with, those static/final variables and enumerations cannot help. In my opinion, this is the case when we need to use a Singleton class (when we need some unique functions to work with static/final states/values).

Cheers... :))

peter.aryanto
  • 502
  • 3
  • 6
  • did you know that Java enums can have methods of varying visibility and even implement interfaces? I'm not advocating for the abusive overuse of enums, Singletons do have a limited purpose. – dan Apr 21 '23 at 16:55