views:

556

answers:

5

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?

+15  A: 

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
+1  A: 

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
+1  A: 

Use Your singletons wisely

richs
+1  A: 

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
@Nate, this sounds interesting, Could you give me an concrete example?
eric2323223
+8  A: 

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