21

Currently I have been very interested in this "design pattern". I am not sure though if there are downfalls using this strict global state implementation. So, when do you think not to practice singleton in an application?

skaffman
  • 381,978
  • 94
  • 789
  • 754
DragonBorn
  • 9,603
  • 10
  • 35
  • 47
  • [Here](https://www.michaelsafyan.com/tech/design/patterns/singleton) is a good read on singleton being an anti-pattern. – RBT Oct 25 '16 at 06:31

4 Answers4

38

Singleton is generally a bad idea if you are doing unit testing, and its generally a bad idea not to do unit testing (or BDD or Acceptance Testing).

Making objects have global state means that the unit tests you write involving these objects will be isolated and disjoint from one another. Instead, you will have to worry about resetting the state for each test and believe me ... that is never done 100% of the time. If you don't reset the global state then you start to get very weird and hard to debug errors in your tests that waste time.

Global state also increases coupling in your code and makes it very hard to refactor.

The ideal method would be to use an IoC/DI container (Spring, Guice, etc.) to request objects. These containers often have ways of making objects appear as 'Singletons' but they also have ways of modifying that behavior depending on the situation (i.e. unit testing vs. your domain code).

This all depends on the size of your problem of course. If you're hacking together a 4-class test rig to try something out then go ahead and use a Singleton. However, as soon as that project takes on life and grows bigger and more complex then refactor the Singleton out.

Jeffrey Cameron
  • 9,127
  • 10
  • 42
  • 76
  • 1
    So do you mean that singletons are *never* eligible for use in real projects (and spotting a singleton in a real project automatically equates to code smell regardless of the use case)? – Pacerier Jun 24 '14 at 23:57
  • Do refrain from smelling thyself then. Your answer suggests that singletons are only used for "initial phase" code and should be factored out in all mature projects that grows bigger. So do you mean that singletons are never eligible for use in these projects, or are there valid use cases? – Pacerier Jun 25 '14 at 15:16
  • Very well. Singletons in real projects are a code smell, regardless of the use case and the size of the project. Using the DI pattern (with a specific container if you choose) completely negate the need for them and Singletons result in solutions that are more tightly coupled and harder to maintain in the long term. – Jeffrey Cameron Jun 25 '14 at 19:34
19

Google Tech Talks had some time ago a good presentation about Global State and Singletons. The static singleton pattern is evil, because is causes unwanted side-effects and makes the code untestable. Static singleton is the OO version of global variables.

The solution is to just create one instance of the object and pass it to its users through dependency injection. DI frameworks, such as Guice, make defining the good kind of singletons easy (in Guice just annotate a class with @Singleton). There was a similar Tech Talk called Don't Look For Things! which discussed DI more.

Esko Luontola
  • 71,072
  • 15
  • 108
  • 126
7

In addition to the testing and design issues mentioned in other posts, there are issues with Singletons and classloaders. Singletons aren't really "single" per JVM or application - they accomplish this through the static property, which really means there is one per class. If there are multiple classloaders - like in most app servers - each separate application gets a new classloader, even multiple levels of classloaders are used in EJB. A singleton instance gets loaded per classloader - which depending on what you're doing with the singleton, may not produce the results you expect.

Nate
  • 16,295
  • 5
  • 44
  • 58
  • 1
    @Nate, this sounds interesting, Could you give me an concrete example? – eric2323223 Sep 19 '09 at 16:36
  • Are there authoritative sources for your claim? Why wouldn't separate instances of JRE use separate instances of singletons? – Pacerier Jun 25 '14 at 00:03
  • @Pacerier http://www.oracle.com/technetwork/articles/java/singleton-1577166.html Separate JREs using separate singleton instances is the expected case - the problem is a single JRE can have multiple classloaders and thus multiple singleton instances. – Nate Jun 25 '14 at 13:08
3

I would use a Singleton very rarely. Due to their nature (static, global objects) they are difficult use in unit testing your code. You end up needing to do some synchronization or building in some re-initialization mechanisms so that you can get a fresh version for each unit test. There are cases that make sense -- say, for instance, a global configuration class -- but they are much fewer than people new to singleton seem to believe. I know I went through a phase where I saw applications of the singleton pattern everywhere. Now I avoid it wherever I can and undo it via refactoring in my code as I come across an unnecessary implementation.

tvanfosson
  • 490,224
  • 93
  • 683
  • 780