It’s been years since I’ve gone on an Anti-Singleton rant

So apparently it’s time again:

See:

TDD Design Starter Kit – Static Methods and Singletons May Be Harmful

and

Chill out on the Singleton Fetish

 

TypeMock will make singletons and statics “testable” now, but you’ll still get screwed over with very tight coupling. 

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @James,

    Yeah, just rub it in that your little dynamic language makes unit testing easier…

  • http://jlorenzen.blogspot.com James Lorenzen

    Appreciate the articles on why the singleton pattern is over used. Just as a side note, I was recently doing some side work in grails/groovy and had to figure out how to test a service that used static methods (not by choice). Specifically, I had to mock out Thread.startDaemon(). It’s rather easy in groovy (not sure you care) but thought it was worth mentioning.

    To see the full example go here http://jlorenzen.blogspot.com/2008/07/groovy-threads-and-metaclass-example.html

  • rprotus

    When I need to use a singleton I use a template wrapper similar to the one in the Ace toolkit. A scrubbed version of the one I use now is included below (even including my original anti-proliferation comments). Anyway, the main benefits are 1) Standardized interface to accessing instances. 2) Class logic is independent of the singleton feature. 3) Ability to free up the memory if needed before program exit.

    The friend functions just give a more convenient usage that reads nicer too.
    Instance().Bar(); // using Instance friend function
    vs
    Singleton
    ::Instance().Bar();

    /// Can turn ordinary classes with default constructors into Singletons.
    /// The proliferation of singletons is discouraged, however where the use
    /// is justified, this class will make singletons easier to create and
    /// standardize the interface.
    ///
    /// If you want to make sure that only the singleton instance of is
    /// created, and that users cannot create their own instances of
    ,
    /// do the following to class
    :
    /// (a) Make the constructor of
    private (or protected)
    /// (b) Make Singleton a friend of

    /// Here is an example:
    /// \code
    /// class Foo
    /// {
    /// friend class Singleton;
    /// private:
    /// Foo () { cout < < "foo constructed" << endl; }
    /// ~Foo () { cout << "foo destroyed" << endl; }
    /// };
    /// \endcode
    template class Singleton
    {
    friend T& Instance();

    friend void InstanceCleanup();

    T mInstance;

    static Singleton*& rpSingleton();
    {
    static Singleton
    * sp_singleton(0);
    return sp_singleton;
    }

    Singleton()
    {
    }

    static T& Instance()
    {
    Singleton*& rp_singleton(rpSingleton());
    if (0 == rp_singleton)
    {
    rp_singleton = new Singleton
    ;
    }
    return rp_singleton->mInstance;
    }

    static void CleanUp()
    {
    delete rpSingleton();
    rpSingleton() = 0;
    }

    };

    template T& Instance();
    {
    return Singleton::Instance();
    }

    template void InstanceCleanup()
    {
    Singleton::CleanUp();
    }

  • Chen Li

    I’ve seen many complaints about Singleton and I’ve seen many code which leverages Singleton as the last resort to obtain the accessibility of some root nodes. but still, it’s not fair to blame Singleton itself.
    I agree with Brain, the key point is to evaluate carefully when it’s appropriate to use it.

  • http://randomcode.net.nz Neal

    * spooky whisper *
    I see dead kittens…..

    okay so I’ve probably had not enough sleep and too many M&Ms but it was the first thing that came to mind when I saw the image.

  • http://www.rasmuskl.dk Rasmus Kromann-Larsen

    Defining singleton-like behaviour in StructureMap is so much more easy than creating them anyway. <3 AsSingleton().

    I don’t understand why anyone would both with all the lazy fudge and borked double-checked locking.

  • Brian Johnston

    Absolutely! (re: knowing better about blindly following something just because it’s in the GoF book)

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Brian,

    “Perhaps I misread your comment, but the implication that people will get screwed over using singleton when they may be using the pattern correctly seems a bit dooms day to me. ”

    You didn’t misread it at all. You can do a perfect GoF implementation of a Singleton, and end up getting screwed later on because you can’t easily remove the dependencies on the Singleton and everything underneath it. That’s personal experience btw, not conjecture.

    Yeah, you can get away with a Singleton by making it easy to replace the internal single instance, but then you’ve still got a hidden, opaque dependency. DI is always going to be more intention revealing, and you can just let an IoC tool handle the Singleton lifecycle instead of wasting time rolling singletons by hand.

    And if the rumor is true, the surviving GoF members are writing a version 2, with very explicit warnings about Singleton abuse.

    Lastly, and I bet you know better anyway, don’t ever for a second think that something is good just because it’s in the GoF book.

  • Brian Johnston

    Singleton isn’t always a bad thing otherwise the GoF wouldn’t of made a pattern out of it. There are places where it’s appropriate to use, and places where it’s not appropriate to use (which will result it one screwing themselves as you so put it, and I certainly agree with that).

    Like all things, knowing when to use it and when not to use it is the key. Your reference to a ‘TDD’ friendly way of doing static operations is definite option in many cases that people over-look unfortunately. Perhaps I misread your comment, but the implication that people will get screwed over using singleton when they may be using the pattern correctly seems a bit dooms day to me. If I read it incorrectly I apologize.

    The problem isn’t the tool, it’s the person using the tool. That’s what needs to be fixed/educated, and no ‘tool’ in the world, no matter how limiting (or unlimiting) it is will fix that, only instruction and experience will cure that.

  • http://robinclowers.blogspot.com Robin Clowers

    Your image seems to be broken…