|
WhySingletonsAreControversial
A brief explanation of the problems with singletons.
Why Singletons Are ControversialThe use of singletons is actually a fairly controversial subject in the Java community; what was once an often-used design pattern is now being looked at as a less than desirable coding practice. The problem with singletons is that they introduce global state into a program, allowing anyone to access them at anytime (ignoring scope). Even worse, singletons are one of the most overused design patterns today, meaning that many people introduce this possibly detrimental global state in instances where it isn't even necessary. What's wrong with singletons' use of global state? First, programs using global state are very difficult to test. One of the hallmarks of testability is a loose coupling of classes, allowing you to isolate a single class and test it completely. When one class uses a singleton (and I'm talking about a classic singleton, one that enforces it own singularity thorough a static getInstance() method), the singleton user and the singleton become inextricably coupled together. It is no longer possible to test the user without also testing the singleton. In many cases, this is a deal breaker that can prevent a developer from testing a class at all, especially if the singleton represents a resource that should not be updated by tests (i.e. an important database). The ideal solution here is to pass in the singleton as a parameter in the user's constructor, allowing a tester to easily mock out the singleton for tests. The singleton then doesn't have to enforce its own singularity; this can be handled by the client or a factory class, which could produce the real version or a test version, eliminating the global state altogether. In fact, it should be considered a violation of the Single Responsibility Principle of OO design to have an object responsible for its own singularity as well as its normal tasks. Second, programs that rely on global state hide their dependencies. One of the unique abilities of a singleton is that it can be accessed anywhere though its globally available static method (i.e. getInstance()), allowing programmers to use it inside of a method without having to pass it in expressly through parameters. While this may seem easier to the programmer, relying on this static instance means that the signatures of methods no longer show their dependencies, because the method could pull a singleton “out of thin air.” This means that users need knowledge of the inner workings of code to properly use it, making it more difficult to use and test. Tying these two problems together shows another issue with singletons. In todays world of test-driven and agile development, it is more important than ever to have small tests covering most of your code. One of the important things about these tests is that they must be able to be run in any order (not dependent on each other), which can become a problem with singleton usage. Because the dependencies of some given methods aren't clear when they rely on singletons (getting them from static getters), a tester may unknowing write two tests that actually depend on each other by modifying a shared resource (the singleton). This can produce flaky tests, ones that pass when run in one order but fail when run in another, which aren't very useful. Still not convinced? Well, this certainly wasn't originally my idea, and it's not even that new. If you're looking for some more compelling arguments, check out some of these sources: All pages with Singleton in their title at the Portland Pattern Repository Wiki Use Your Singletons Wisely (IBM developerWorks) |
Sign in to add a comment
In most cases a singleton is equivalent to a class consisting only of static attributes and methods. Why is this a bad smell to most developers, whereas the singleton isn't? Maybe because the latter is a well known pattern?
No, with the latter you can take advantage of inheritance.
Another problem with a static class implementation is that you may later find the need to change from having a single global instance to multiple context-based instances. With a static class, you will wind up having to rewrite a lot of static references in your code.
singletons are definitely not a global var, singleton should be thread-safe, multi-thread-safe and synchronized, you may dream to accomplish this Job with global vars, especially if you have singletons in a shared Object(s)/Librarie(s).
this is by the way the definition of singleton design pattern, in Java and Objective-C it's really easy to accomplish and there is a big use of this pattern especially in Desktop Application. I n C++ it can be painful except with Boost :), there are several folks who wrote interesting stuff about singletons in C++, one of essential aspect of singleton pattern is the multi-thread support with a mutex/lock mechanism, the next version of STL/C++ should include this natively in the same way than Objective-C/ Class Struct where every Object has a mutex property.
And finally, to answer to the author, there is no controversial/trivial point, as Developer you are supposed to know what you are doing and understand basic OO design pattern if you do not, chose another Job! Code is really not for you.
-Tchuss
you may use OCaml and stop doing Java, it could help :), there are several developers who are using Singletons in a proper way, detect them if you want this is for me what you wrote, is useless, try to replace a brain by a poor parsing tool, LOL, it's like machine learning, it's totally void, we should spend this energy in other fields, like change the way we are building machine, change our electronic view, you will never accomplish such things on our actual tech, yes sure it's working a bit but comparison of the billions of $ put in this field...
When one class references another class, it is coupled to that class, period. It does not matter if either class is a singleton. Coupling is unavoidable in software. You can not reduce it by avoiding the singleton pattern.
Further, the 'getInstance()' method of a singleton gives you a reference to an object. At that point, you don't care if the object is singleton or not, so long as it exposes it instance methods instead of statics.
There is a time and a place for singleton. The real problems with singletons are the problems with all statics - holding memory, synchronizing initialization and access, etc.