As an Agile Coach, Miško is responsible for teaching his co-workers to maintain the highest level of automated testing culture, allowing frequent releases of applications with high quality. He is very involved in Open Source community and an author of several open source projects. Recently his interest in Test Driven Developement turned into http://TestabilityExplorer.org with which he hopes will change the testing culture of the open source community. Misko is a DZone MVB and is not an employee of DZone and has posted 38 posts at DZone. You can read more from them at their website. View Full User Profile

Root Cause of Singletons

08.29.2008
| 5532 views |
  • submit to reddit

Since I have gotten lots of love/hate mail on the Singletons are Pathological Liars and Where Have All the Singletons Gone I feel obliged to to do some root cause analysis.

Lets get the definition right. There is Singleton the design pattern (Notice the capital “S” as in name of something) and there is a singleton as in one of something (notice the lower case “s”). There is nothing wrong with having a single instance of a class, lots of reasons why you may want to do that. However, when I complain about the Singletons, I complain about the design pattern. Specifically: (1) private constructor and (2) global instance variable which refers to the singleton. So from now on when I say Singleton, I mean the design (anti)pattern.

I would say that at this point most developers recognize that global state is harmful to your application design. Singletons have global instance variable which points to the singleton. The instance is global. The trouble with global variables is that they are transitive. It is not just the global variable marked with static which is global but any other variable/object which is reachable by traversing the object graph. All of it is global! Singletons, usually are complex objects which contain a lot of state. As a result all of the state of Singleton is global as well. I like to say that “Singletons are global state in sheep’s clothing.” Most developers agree that global state is bad, but they love their Singletons.

The moment you traverse a global variable your API lies about its true dependencies (see: Singletons are Pathological Liars) The root problem is not the Singleton design pattern, the root problem here is the global reference to singleton. But the moment you get rid of the global variable you get rid of the Singleton design pattern. So from my point of view blaming Singletons or blaming global state is one and the same. You can’t have a Singleton design pattern and at the same time not have the global state.

Someone pointed out that any design pattern can be abused. I agree, but with Singleton design pattern, I don’t know how I can possibly use it in a good way. The global reference and hence the global state is ever so present. Now, in my line of work I don’t see too much global state in classical sense of the word, but I see a lot of global state masquerading as Singletons. Hence, I complain about Singletons. If I would complain about global state no one would care, as that is old news.

Now, there is one kind of Singleton which is OK. That is a singleton where all of the reachable objects are immutable. If all objects are immutable than Singleton has no global state, as everything is constant. But it is so easy to turn this kind of singleton into mutable one, it is very slippery slope. Therefore, I am against these Singletons too, not because they are bad, but because it is very easy for them to go bad. (As a side note Java enumeration are just these kind of singletons. As long as you don’t put state into your enumeration you are OK, so please don’t.)

The other kind of Singletons, which are semi-acceptable are those which don’t effect the execution of your code. Logging is perfect example. It is loaded with Singletons and global state. It is acceptable (as in it will not hurt you) because your application does not behave any different whether or not a given logger is enabled. The information here flows one way: From your application into the logger. Even thought loggers are global state since no information flows from loggers into your application, loggers are acceptable. You should still inject your logger if you want your test to assert that something is getting logged, but in general Loggers are not harmful despite being full of state.

So the root cause is “GLOBAL STATE!” Keep in mind that global state is transitive, so any object which is reachable from a global variable is global as well. It is not possible to have a Singleton and not have a global state. Therefore, Singleton design patter can not be used in “the right way.” Now you could have a immutable singleton, but outside of limited use as enumerations, they have little value. Most applications are full of Singletons which have lots of global state, and where the information flows both directions.

From http://misko.hevery.com

Published at DZone with permission of Misko Hevery, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

David Lee replied on Fri, 2008/08/29 - 9:35am

I read this and I all I can say is "What?".  You justified a case, albeit you call it semi acceptable, but nevertheless you justify their usage.  You've probably given this more thought than I have but you do say in your line of work you don't see much global state.  Don't all servlet based web applications have global state ? I see in many libraries access to the context is available via a singleton object.  It seems as though you're saying this is a bad practice.   If so, why ?  

 

I'd like a response but you've set off my "caution"  system. Whenever a developer talks about "the right way" usually it means "my way", or the "way I like".  In many cases, not all,"right" is so subjective and relative to what you're doing that there is always more than one "right" way.  There can and very often always will be better ways, but "right" is always in the eye of the beholder, even when it is right.

Terrell Deppe replied on Fri, 2008/08/29 - 9:47am

"Since I have gotten lots of love/hate mail..."

Don't listen to the haters. You obviously "get it".

James McGivern replied on Fri, 2008/08/29 - 10:42am

I agree with David Lee, my caution alarm went off. If you say "with Singleton design pattern, I don’t know how I can possibly use it in a good way" I read it as "I can't think of a good use therefore its bad" - not the best interpretation maybe but...

I have seen several good uses of the Singleton design pattern, from Spring to Eclipse. Just because you can't think of one doesn't mean they are bad. Also just because you see lots of people abusing a design pattern doesn't make the pattern bad its the programmers. Is it possible that what in fact is happening is that you are being a good programmer who realises that using it left, right, and centre is not the best thing? That maybe you have an apprication of what to use where? That maybe others don't? Should we remove threading since most people abuse that too?

Mark Thornton replied on Fri, 2008/08/29 - 11:58am

In applications which live within a container there is a straightforward way to share context without resorting to the Singleton pattern. However many Java application areas have no such standard facility, and so fall back on the Singleton pattern. In a sense this is still a container pattern, where the container is the ClassLoader. If you are prepared to play with ClassLoaders you can have multiple instances of a Singleton (excluding those that involve JNI).

Filip Ristić replied on Sat, 2008/08/30 - 6:59am

OK, I have some issues regarding this discussion. I understand part about global state, but I don't know if I understand problems with hiding dependencies. If this code is hiding dependencies:

public void doSomething(){
ClassA classA = ClassA.getInstance();

// do something
}

then I think it is also the case with following snippet:

public void doSomething(){
ClassA classA = new ClassA();

// do something
}

Basically, I don't see any difference in these two approaches. In other words, I think it is not Singleton who is hiding dependencies, but the function itself. Am I right?

Petrukhin Vladimir replied on Sat, 2008/08/30 - 9:20am

The problem is not in singletons. Modern languages is not good.  No good ways to represent business dependencies and low level(technical) dependencies. And we have to use this small capabilities and we have to have hot discussion... All of this is not right... (

Slava Imeshev replied on Sat, 2008/08/30 - 8:00pm

It is kind of funny how consistently many try to pick on the Singleton pattern and consistently fail to make the case. This posting is an example of such an attempt.

Singleton is just a pattern and as such, it has its benefits and drawbacks. It is not good or bad on its own. It is how one uses or misuses it makes it good or bad.

Regards,

Slava Imeshev

Władysław Łokietek replied on Sun, 2008/08/31 - 3:46am

So it all comes down to considering making singletons from objects to/from which data flows only in one direction, or doesn't have any state and you only would ever need one instance. So the key here is state. If some object is hiding some state it should be considered instance variable. Thanks for the article.

barneypitt replied on Sun, 2008/08/31 - 12:31pm

Name: Misko Hevery

Specialist Subject: The Bleeding Obvious

barneypitt replied on Sun, 2008/08/31 - 1:00pm

Okay, I realise that comment was curt. But this kind of article riles me.

Everyone, <b>everyone</b> knows that singleton == global state. By definition. That's not up for discussion, nor is it interesting. There is, of couse, an interesting issue underlying the use of the singleton (or identically, global state) which is - "if it is so bad, why does everybody do it"? And as with most "anti-patterns" the answer is "because it is so damn useful". The trick is to use it safely and appropriately.

How not to use global state:

     public static final ConcurrentHashMap<MyKey, SomeObjectWhichMayChange> = ...;

How to correctly use global state:

     public static final ConcurrentHashMap<MyKey,  SomeObjectWhichCannotChange> = ...;

Pretty simple.

 

Aidos Morg replied on Mon, 2008/09/01 - 12:05am

I don't think that a Singleton deserves to be called an anti-pattern, I agree however that it does get abused way too much.

I understand your reasoning for the "global state" argument, and you are correct, but I think the reason it gets abused boils down to two different aspects:

 1.  It is the easiest pattern to understand. Most undergraduates are given a very quick introduction to patterns and the Singleton is the one that is definately the easiest to understand. I can't count the number of prospective graduate engineers who I have interviewed that can only recite Singleton as an example of a design pattern. The same goes for more senior engineers who missed out on learning about patterns when they were at uni and have grabbed the GoF to try to learn. It's ease of understanding is definately part of it's abuse.

 2. Singleton's make it easy to forget about how object lifecycles should work. I have seen countless thousands of uses of Singletons that are because the developer thinks "I need to make a call on A from here in B, I know, I'll just make A a Singleton", instead of actually thinking about correct architectural design, or refactoring some code so that B can see A through some sort of context. This boils down to either lazyness, lack of understanding of good architectural design or deadlines.

Generally when I am performing a code review, if I see a Singleton I make the developer give me very good reasons why it needs to be a Singleton. Honestly about 90% of uses are wrong because of the reasons listed in point 2. There is also 10% of times that are definately valid (Eclipse, Spring, J2EE Home Interfaces etc.)

 

Chris Merrill replied on Wed, 2008/09/03 - 10:28am

Someone pointed out that any design pattern can be abused. I agree, but with Singleton design pattern, I don’t know how I can possibly use it in a good way.

Then you have not looked very far.

 

Jordan Zimmerman replied on Wed, 2008/09/03 - 2:37pm

Another in a long line of quais-religious screeds on how to program the "right way". As several have pointed out above, all this article describes is why the writer doesn't like singletons, not why they are bad. The writer makes many unsubstantiated claims that are really just opinions.

Used judiciously, the Singleton Pattern is an excellent choice. 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.