Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why implementing a Singleton pattern in Java code is (sometimes) considered an anti-pattern in Java world?

I have seen some people in SO commenting that Singleton Pattern is an anti-pattern. I want to know why ?

like image 723
Inquisitive Avatar asked Jul 02 '12 10:07

Inquisitive


People also ask

Why is the Singleton pattern considered to be an anti pattern?

If singleton were used here, it would break that behavior. This inflexibility is one of the biggest reasons why singleton is an antipattern. Engineers often use singletons to provide a global access point. They are often used in place of a global variable that has a single instance.

What is the disadvantage of Singleton pattern in Java?

One of the main disadvantages of singletons is that they make unit testing very hard. They introduce global state to the application. The problem is that you cannot completely isolate classes dependent on singletons. When you are trying to test such a class, you inevitably test the Singleton as well.

Which is the reason to implement the Singleton design pattern in your application?

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.

What is the problem that Singleton pattern solve?

The singleton design pattern solves problems by allowing it to: Ensure that a class only has one instance. Easily access the sole instance of a class. Control its instantiation.


5 Answers

Testing

One reason is that singletons aren't easy to handle with unit tests. You can't control the instantiation and by their very nature may retain state across invocations.

For that reason the principle of dependency injection is popular. Each class is injected (configured) with the classes they need to function (rather than derive via singleton accessors) and so tests can control which dependent class instances to use (and provide mocks if required).

Frameworks such as Spring will control the lifecycle of their objects and often create singletons, but these objects are injected into their dependent objects by the framework. Thus the codebase itself doesn't treat the objects as singletons.

e.g. rather than this (for example)

public class Portfolio {    private Calculator calc = Calculator.getCalculator(); } 

you would inject the calculator:

public class Portfolio {    public Portfolio(Calculator c) {       this.calc = c;    } } 

Thus the Portfolio object doesn't know/care about how many instances of the Calculator exist. Tests can inject a dummy Calculator that make testing easy.

Concurrency

By limiting yourself to one instance of an object, the options for threading are limited. Access to the singleton object may have to be guarded (e.g. via synchronisation). If you can maintain multiple instances of those objects, then you can tailor then number of instances to the threads you have running, and increase the concurrent capabilities of your codebase.

like image 53
Brian Agnew Avatar answered Sep 29 '22 01:09

Brian Agnew


My personal opinion is that it violates the single responsibility principle. Singleton objects are responsible for both their purpose and controlling the number of instances they produce which I think is wrong.

This is why a lot of people delegate the control to a factory object.

like image 20
MikePatel Avatar answered Sep 29 '22 03:09

MikePatel


[Mutable] Singleton is an anti-pattern of an anti-pattern.

The significant underlying anti-pattern is global state (or ambient state). With global state you have a big blog of dependency across your program. This does affect testing, but that's just a one part of the fallout from bad programming.

Layered upon that, Singleton adds completely unnecessary level of complexity over simply declaring mutable static fields.

like image 24
Tom Hawtin - tackline Avatar answered Sep 29 '22 03:09

Tom Hawtin - tackline


Singletons as such are not necessarily an anti-pattern, but they have only few benefits and become an antipattern when they are used wrong (which happens often).

Often, singletons are not singletons at all, but "global variables in disguise". Also, often they are used when the "only one instance" property is actually not an advantage. (which again is balanced by the fact that many times the implementation is wrong at the same time).

In addition to that, they can be tricky to implement with multithreading in mind (often done wrong or inefficiently), and they lose most of their benefits if you want to control their instantiation.

If you want to have control over instantiation, you need to do it by hand at some point early in the program, but then you could just as well just create one instance of a normal object and pass that onward.
If order of destruction is of any concern, you need to manually implement this as well. A single automatic object in the main function is just so much cleaner and easier.

like image 31
Damon Avatar answered Sep 29 '22 03:09

Damon


There are many requirements that you might have on the singleton:

  1. lazy initialization;
  2. proper disposal;
  3. scoping (one per thread, for example).

Typically, also, you'll have a whole lot of singletons in your app, and the Singleton pattern doesn't allow reusable code. So, if you want to implement all these concerns for all your singletons, you'll immediately see its anti-pattern quality.

like image 24
Marko Topolnik Avatar answered Sep 29 '22 03:09

Marko Topolnik