Root Cause of Singletons

August 25th, 2008 · 17 Comments ·

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.

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • De.lirio.us
  • E-mail this story to a friend!
  • Reddit
  • Slashdot
  • StumbleUpon
  • Blogosphere News
  • description
  • TwitThis

Tags: Advice · Rant · Testability

17 responses so far ↓

  • Glen Scott - Keeping it simple, since 1977 » Singletons and global state // Aug 27, 2008 at 12:32 am

    [...] Root Cause of Singletons [...]

  • redsolo // Aug 27, 2008 at 12:36 am

    I must say I really like your posts on Singletons. I have come to detest the pattern as it makes it impossible to test code with. My answer for why people are using it, is because they are lazy. It is so much easier adding logic/data to a Singleton than making it separate and changing a lot of classes to get the data to the requesting class.

  • Paul Houle // Aug 27, 2008 at 9:07 am

    I see things differently.

    I can see how “Global State” impacts your desires for testability. However, appropriate use of “Global” or semi-Global states can greatly simplify the design of applications as well as improve reliability in performance.

    In web applications, for instance, there is a natural “Global” state associated with a web request. In PHP that’s quite literally a global state, and in ASP.NET. For most web apps, you want “global” access to the ip address of the requestor and to the database connection that you’re using. People who are afraid of globals invariabily end up:

    (i) creating ‘local’ database connections that are wasteful (I clocked one app that went down this road and ended up creating 300 connections to the same database to serve a request!) and make it difficult or impossible to use transactions in a correct manner
    (ii) using the “sawzall antipattern” where they need to modify the signature of 15 methods so they can pass an object (like a database connection or the ip address of the requestor) from the place where it’s available to where it’s available. A one-line code change that one programmer could do in twenty minutes becomes a matter of 30 lines of code that cross several boundaries thus requiring three or four meetings to make the change.

    It’s not always lazy to use global states: often it’s DRY and often it results in radically simpler code that lets you focus on the difficult parts of your work.

    In my mind, the “root cause” of Singletons is the weakness of inheritance and polymorphism in mainstream languages where statics are concerned. That is, people often use Singletons where they really want to use a static class.

    The Multiton pattern gives many of the benefits of Singletons while still having the ability to partition the application (for testability and other purposes.) See

    http://gen5.info/q/2008/07/25/the-multiton-design-pattern/

  • misko // Aug 27, 2008 at 9:34 am

    @Paul Houle

    I would like to politely disagree with you. Your counterexamples only stand to demonstrate that you have not yet understood what I am trying to get to.

    1) Creating a new connection per request is dumb. I agree. You need to have a single object responsible for caching it. But that object should not be Singleton (global state) but a singleton (one instance).

    2) I never heard of “sawzall” but I think I have seen it many times before, so I think I know what you are talking about, and yes it is an anti-pattern. See Breaking the law of Demeter When this happens you are doing dependency injection the wrong way.

    3) A http request is not global, at best it is thread local. (otherwise you could not have multi-threaded request to your web server) However, using global state is wrong here as well. You can design a nice clean application without resorting to any of these.

    Global state impacts: testability, understandability, maintainability, and scalability, and probably few other -abilities.

    You can build apps global state free, and once you see those apps, the first thing you notice is just how clean the code is and you instantly fall in love with them.

    Getting rid of global state actually makes your code better and cleaner.

  • wekempf // Aug 27, 2008 at 11:43 am

    You’ve done a lousy job explaining the difference between Singleton and singleton. Where does a singleton come from? How do you enforce the fact that there should be only one? IOW, how exactly does a Singleton differ from a singleton?

    In any case, your original post was still HUGELY in error. If all of your Singleton examples actually were Singletons, none of the issues you pointed out would have occurred. The Singleton pattern IS a factory, and ensures none of the things you complain about can occur. The init() calls in your examples mean that you did NOT follow the pattern, and THAT is your problem.

    I’m not arguing that the Singleton pattern doesn’t have issues, and isn’t over used by developers. But we can’t have that discussion until you’ve proven you understand the subject we’re talking about.

  • Casper Bang // Aug 27, 2008 at 11:47 am

    Yes, a singleton can be abused. Get over it, so can if statements. A few things often left out of the debate:

    Singletons solves an important discovery and hence usability problem. If you, the designer of an application, decides there should only ever be one, but it can change, then you should be entitled to. Thank goodness a Swing app can only have one have one L&F at a time due to UIManager.getLookAndFeel.

    Contrary to common belief, singletons are easily mockable by simply using a SPI approach (program to an interface). Let the classpatch do the depdendency injection rather than you having to add arbitrary layers of indirection in annotations or XML.

    PS: For a post that goes to great length trying defining concept vs. pattern, I wonder why you would toss around the world “enumeration” so freely. An SE1.4 or ME developer will be thinking of java.util.Enumeration but I guess you really mean the SE5 enum construct.

  • todd // Aug 27, 2008 at 12:58 pm

    A singleton is more of a service access point than it has anything to do with making sure there’s only one of something. So when you test simply set the instance you want the singleton to return so all test code works like normal. Only the test setup is different. Simple.

    In this view a singleton is global for perfectly good reasons, it is supposed to be how independent modules access a shared service. The program startup environment can act as a factory setting the correct instance for the environment.

  • Frank // Aug 27, 2008 at 1:02 pm

    @Casper
    Singletons and unnecessary global state are abused much more often than ‘if’ statements. I’d be interested in hearing how you use the classpath to mock and and to ensure cleanup of singletons in a testing context. Are you confusing “dependency injection” with some kind of “classpath constructor polymorphism”?

  • Casper Bang // Aug 27, 2008 at 1:53 pm

    “Singletons and unnecessary global state are abused much more often than ‘if’ statements.”

    Umm not so sure about that. I see an awful lot of ‘if’ being used in quadrupoled nested scopes, to handle null or because the developer have yet to see the OO polymorphism light. I’m surprised my RSS feed haven’t yet delivered an ‘if is evil’ heading although I expect when the singleton has been ponded enough that will come.

    “Are you confusing ‘dependency injection’ with some kind of ‘classpath constructor polymorphism’?”

    No I don’t believe I am, you just appear to acknowledge only to the Hollywood version (don’t call me, we’ll call you). With an SPI approach, dependency resolution is controlled by my Ant script (thus a test implementation of SomeService can differ from the real impl of it).

    How would you implement the Swing L&F mechanism without global state? You agree that components would need somewhere to register themselves such as to receive notifications when a new L&F is set etc?

  • My main() Method Is Better Than Yours | Miško Hevery // Aug 29, 2008 at 5:53 pm

    [...] test-doubles. (I know we can fight static with static, but we already said that global state is bad here, here and here). The reason we can’t test this is that the moment you execute the main method [...]

  • Singletons are Pathological Liars | Miško Hevery // Sep 10, 2008 at 10:33 am

    [...] Follow up: Root Cause of Singletons ] Share and [...]

  • Brendan Miller // Sep 10, 2008 at 2:23 pm

    Singleton’s have concerned me for a while, but I think there is a way to fix the pattern. The original idea behind the pattern was that you would have a means of controlling the number of objects of a class that could be instantiated. For instance, if you have an object that gets exclusive access to some hardware device that can’t be shared within the process, you don’t want someone accidentally instantiating two instances.

    However, if you ever call getInstance() more than once in your program, you end up just using singleton’s like global variables… and if you can remember to *not* call getInstance() more than once, than you really got no benefit over just calling a constructor only once. So proper use of the pattern with dependency injection negates the benefits of the pattern.

    Maybe a pattern that would actually achieve the goal that singleton fails to achieve would be a one shot static factory. The first time you call CreateInstance() it succeeds, and on subsequent attempts it returns null.

    The pros of this approach as I see it would be that you can easily control the number of objects, and increase the number of objects that can be created in the future for instance, if you decide to allow one object for each calling thread, or if you figure out a way to allow many objects to concurrently access a resource. Allow more objects just means relaxing the “call once” interface in a backwards compatible way.

    The con is that one shot static factories themselves are inherrently stateful. However, if the created objects cannot safely coexist with other objects of the same class, than that statefulness already exists, but the one shot makes it exlicit and localizes the statefullness to the static factory method. In cases where you are only creating one instance for efficiency (i.e. a database connection) then I’m not sure if there is a strong case above simply remembering to only call the constructor once.

  • Where Have all the “new” Operators Gone? | Miško Hevery // Sep 10, 2008 at 5:40 pm

    [...] here are few thoughts on my love/hate of Singletons (mentioned here and here) First a little review of singletons. A singleton with a lower case ’s’ is a good [...]

  • Application Wiring on Auto-Pilot | Miško Hevery // Sep 24, 2008 at 10:37 am

    [...] the scope of this article, such as manage object lifetimes, enforce singletons (in a good way, see: Root Cause of Singletons and Singletons are Pathological Liars) and manage different configurations of your application [...]

  • Singleton I love you, but you're bringing me down | // Coding Without Comments // Oct 8, 2008 at 9:11 pm

    [...] code execution remains the same. Enable it, same same. Misko puts it in the following way in Root Cause of Singletons, “The information here flows one way: From your application into the logger. Even though loggers [...]

  • Dependency Injection Myth: Reference Passing | Miško Hevery // Oct 21, 2008 at 8:01 am

    [...] reading the article on Singletons (the design anti-pattern) and how they are really global variables and dependency injection suggestion to simply pass in the reference to the singleton in a [...]

  • Larry singleton // Oct 28, 2008 at 8:01 am

    having singletons in the global code is essential for the design of greater singleton truth. singletons are not all a controlled mechenism ,althought thought can be that if you use them well then good is explained, but if you do not like singletons then what [ no code ] that is not essential to what and how it is being used…

Leave a Comment