Where Have All the Singletons Gone?

August 21st, 2008 · 24 Comments ·

by Miško Hevery

In Singletons are Pathological Liars we discussed the problems of having singletons in your code. Let’s build on that and answer the question “If I don’t have singletons how do I ensure there is only one instance of X and how do I get X to all of the places it is needed?”

An OO application is a graph of objects. There are three different kinds of graphs I think of when I design an application

  1. Collaborator Graph: This is the graph of objects that would be emitted if you serialized your application. This shows which objects are aware of which others. (through object’s fields)
  2. Construction Graph: This graph shows which object created which other ones.
  3. Call Graph: This graph shows which other methods each method calls. A stack-trace would be a single slice through this graph.

If the new operators are mixed with application logic (see: How to Think About the new Operator) then the Constructor Graph and the Collaborator Graph tend to be one and the same. However, in an application which uses Dependency Injection the two graphs are completely independent. Lets have a closer look at our CreditCardProcessor example. Suppose this is our collaborator graph which we need to execute a request.


The above shows the application collaborator graph. The letter (S/R) in the corner designates object lifetime; either Singleton or Request scope. Now, just to be clear, there is nothing wrong with having a single instance of a class. The problem arises only when the singleton is available through a global “instance” variable as in Singleton.getInstance().

The HTTP request would come to AuthenticatorPage which would collaborate with Authenticator to make sure the user is valid and forward a valid request onto ChargePage which would then try to load the user from UserRepository and create the credit card transaction which would be processed by CrediCardProcessor. This in turn would collaborate with OfflineQueue to get the work done.

Now, in order to have a testable codebase we have to make sure that we don’t mix the object construction with application logic. So all of the above objects should rarely call the new operator (value objects are OK). Instead each of the objects above would declare its collaborators in the constructor. AuthenticatorPage would ask for ChargePage and Authenticator. ChargePage would ask for CreditCardProcessor and UserRepository. And so on. We have moved the problem of construction elsewhere.

In our tests it is now easy to instantiate the graph of objects and substitute test-doubles for our collaborators. For example if we would like to test the AuthenticatorPage, we would instantiate a real AuthenticatorPage with mock ChargePage and mock Authenticator. We would than assert that a request which comes in causes appropriate calls on Authenticator and ChargePage only if authentication is successful. If the AuthenticatorPage were to get a reference to Authenticator from global state or by constructing it, we would not be able to replace the Authenticator with a test-double. (This is why it is so important not to mix object construction with application logic. In the unit-test what you instantiate is a sub-set of the whole application. Hence the instantiation logic has to be separate from application logic! Otherwise, it’s a non-starter.)

So now the problem is, how do we construct the graph of objects?

In short we move all of the new operators to a factory. We group all of the objects of similar lifetime into a single factory. In our case all of the singletons end up in ApplicationFactory and all of the Pages end up in RequestFactory. The main method of our application instantiates an ApplicationFactory. When we call build() the ApplicationFactory in turn instantiates its list of objects (Database, OfflineQueue, Authenticator, UserRepository, CreditCardProcessor and RequestFactory). Because each of the objects declares its dependency, the ApplicationFactory is forced to instantiate the objects in the right order. In our case it must instantiate the Database first and than pass the reference to UserRepository and OfflineQueue. (The code will simply not compile any other way.)

Notice that when we create a RequestFactory we must pass in references to the Authenticator, UserRepository and CreditCardProcessor. This is because when we call build() on RequestFactory it will try to instantiate AuthenticatorPage which needs the Authenticator. So we need to pass the Authenticator into the constructor of RequestFactory and so on.

At run-time an HTTP request comes in. The servlet has a reference to RequestFactory and calls build(). The servlet now has a reference to the AuthenticatorPage and it can dispatch the request for processing.

Important things to notice:

  • Every object only has references to what it needs directly! No passing around of objects which are not directly needed by the code. There is no global state at all. Dependencies are obvious since each object only asks for what it needs.
  • If an object needs a reference to a new dependency it simply declares it. This change only affects the corresponding factory, and as a result, it is very isolated.
  • All of the new operators end up in the factories; application logic is devoid of new operators.
  • You group all of the objects with the same lifetime into a single factory (If the factory gets too big you can break it up into more classes, but you can still think of it as a single factory)
  • The problem of “how do I ensure that I only have one of something” is nicely sidestepped. You instantiate only a single ApplicationFactory in your main, and as a result, you only instantiate a single instance of all of your singletons.

Now the factories become largely a series of object creations. Totally boring stuff, so boring a computer could generate the code. Simply look at the constructor and recursively instantiate whatever the constructor wants. Wait, a computer can generate it! Its called PicoContainer or GUICE! So you don’t actually have to write the factories.

Tags: Advice · OO · Rant · Testability

24 responses so far ↓

  • Where Have All the Singletons Gone? // Aug 21, 2008 at 12:02 pm

    [...] Original post by misko [...]

  • Singletons are Pathological Liars | Miško Hevery // Aug 22, 2008 at 6:37 am

    [...] Follow up: Where Have All the Singletons Gone ] Share and [...]

  • Jonathan Hartley // Sep 4, 2008 at 2:30 am

    Thanks for this article. I’m allegedly an experienced developer but I was fuzzy in my understanding of this and you’ve helped me out tremendously. Nice job!

  • R V // Sep 9, 2008 at 10:55 am

    How would you answer the question of whether database connection pools should only be instantiated once, hence be a singleton? Or any kind of pool like a thread pool object pool, etc.
    Thanks.

  • Where Have all the “new” Operators Gone | Miško Hevery // Sep 10, 2008 at 10:28 am

    [...] here is that call-graph and instantiation-graph are one and the same. We looked into this myth in Where have all the Singletons Gone. Notice that the Jetty server calls the TimeServlet which calls the Date. If the constructor of [...]

  • Brendan Miller // Sep 10, 2008 at 5:05 pm

    What tool did you use to make those diagrams btw? I’m looking for a decent tool for making various diagrams for my code.

  • Michael Binette // Sep 11, 2008 at 6:33 am

    Great blog by the way.

    You say “At run-time an HTTP request comes in. The servlet has a reference to RequestFactory and calls build(). ”

    How exactly does the HTTP request get a reference to RequestFactory?

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

    [...] Misko Hevrey (who does testing for google) goes into much greater detail about this technique in his two fantastic blog posts entitled “How to Think About the ‘new’ Operator with Respect to Unit Testing” and “Where Have All the Singletons Gone?” [...]

  • 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 [...]

  • Parag // Oct 22, 2008 at 2:43 am

    Very nice article… Thanks a lot for the excellent explanation.

  • AS3 Dependency Injection and [Autowire] « shaun smith // Mar 14, 2009 at 11:47 am

    [...] you could use a Singleton to hang all your objects on. That would not be cool: link, link, [...]

  • Another Architectural Framework, But Why? « shaun smith // Apr 29, 2009 at 5:48 am

    [...] standard Singleton implementation (that static getInstance method) is severely flawed. Unless you are writing device drivers, there [...]

  • dj_unforgetable // May 17, 2009 at 7:59 am

    It’s fine if I use the ApplicationFactory to get my object references, but I can easily break the singleton lifetime and instantiate a new Database, OfflineQueue, CreditCardProcessor and CreditCard myself, no ?

  • Giorgio Sironi // May 30, 2009 at 2:03 am

    No, because you must not use ‘new’ operators in your business objects (everything is not a factory). But you can use ‘new’ in tests.

  • Manoj Mehta // Jun 8, 2009 at 3:07 pm

    Quick Question:”The problem arises only when the singleton is available through a global “instance” variable as in Singleton.getInstance().”If the Singleton classes don’t expose a getInstance method, how do you propose that an instance of the ApplicationFactory is created by the main function of my application? Also, how does the ApplicationFactory instantiate the Singletons that it contains? Thanks,Manoj

  • misko // Jun 12, 2009 at 12:33 pm

    @Manoj,

    Your main should look like this:

    class Main {
    public static void main(String…args) {
    AppFactory factory = new AppFactory(args);
    MyApp app = factory.create();
    app.run();
    }
    }

    Notice how the code is broken to three phases. Create factory, create app, run app. This makes it testable. No matter what your app, you should fallow this pattern. To got singletons to right places the Factory only creates a single instance and then passes that instance to the constructors of all classes as it calls new. See: http://misko.hevery.com/2009/03/30/collaborator-vs-the-factory/

  • Trevor // Dec 9, 2009 at 3:37 am

    I am going to echo the issue brought up by Michael, and point out that the servlet will still need to access a global variable (or a singleton) to get the instance of RequestFactory.

    For clarity’s sake you should indicate this, since you cannot create the servlet via a modified constructor that takes a RequestFactory object. So the overriding design principal, as stated, is broken at this one point in favor of a simpler approach.

  • misko // Dec 9, 2009 at 7:43 am

    @trevor,

    you may look at http://misko.hevery.com/2009/04/08/how-to-do-everything-wrong-with-servlets/ to see why servlets are a problem.

  • Trevor // Dec 9, 2009 at 1:42 pm

    @misko,

    I agree with you completely about servlets, which is why I imagine almost every java web framework in existence replaces them with something else. The reason I mentioned them is only because the post refers to them directly:

    “At run-time an HTTP request comes in. The servlet has a reference to RequestFactory and calls build().”

    It glosses over how the servlet gets the reference to the RequestFactory. I only mention this because if someone comes to this post and is learning why they shouldn’t use singletons for everything, they will get stuck wondering how to jump through that final hoop.

    Now, while I personally don’t like using servlets, there is a way to give them a dynamic context by using an synchronized initialization servlet that puts an Application instance into the ServletContext. This Application object would hold / provide all of the application necessary configurable objects (offline queue, authenticator, requestFactory, etc).

    For testing, the instance of the Application object can be changed with a different class that provides a different implementation, so you would have your TestApplication instance to replace your ProductionApplication instance.

    This still doesn’t make code that is embedded inside servlets easy to unit test though, since you still need the servlet container.

    I have never used the design I have just mentioned, so I am not sure if it has serious problems or not, but it would be easier to refactor to if someone is migrating an existing Servlet based application (easy enough that it seems like a free way to remove singleton dependencies that would be easier than replacing an existing apps use of servlets all together).

  • Linkroll « Notes worth sharing // Jan 3, 2010 at 11:06 am

    [...] http://misko.hevery.com/2008/08/21/where-have-all-the-singletons-gone/ and http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/, “why singletons cause [...]

  • J. B. Rainsberger // Feb 18, 2011 at 1:45 pm

    If you write focused tests and remove duplication mercilessly, then the code to instantiate collaborators will naturally move up the call stack to the entry point of the application, completely removing the need for singletons. The entry point becomes Miško’s Application Factory.

  • Where Have All the Singletons Gone? (Misko Hevery) | hakre on wordpress // Dec 31, 2011 at 12:42 pm

    [...] Where Have All the Singletons Gone? by Misko Hevery TwitterRedditDiggEmailPrintMoreFacebook This entry was posted in Linked, Pressed and tagged Application Factory, Misko Hever, Singleton. Bookmark the permalink. ← The Clean Code Talks — Inheritance, Polymorphism, & Testing (Misko Hevery) How to avoid “tight coupling” in a WordPress Plugin? → [...]

  • Static methods in Class « xiangcaohello // Apr 15, 2012 at 1:27 pm

    [...] articles I believe that static methods are bad from a testing point of view. You should havefactories instead(maybe using a dependency injection tool [...]

  • Hari Karam Singh // Jul 15, 2012 at 9:44 am

    “No passing around of objects which are not directly needed by the code.”

    I can’t quite get how this is the case from the example presented. As @Trevor hypothesized, I’m a bit confused on the last step.

    Is it because you needn’t pass Database, for example, to AuthenticatorPage so it can pass it on to Authenticator? Instead the application startup gives these dependencies to the Factory which injects them behind the scenes when AuthPage requests an instance of Authenticator?

    If so, won’t it be the case that you’ll be passing the Factory instance around everywhere? How is that any better?

    Sorry, I’m not familiar with java servlets. I’m actually trying to interpret this for a mobile app view hierarchy (in iOS – should I admit that here?? ;) )

Leave a Comment