Curing Singletonitis

A few years ago I have blogged about Singletonitis. Another place, different people, yet the same problem appears again – singletonitis. The issues I have outlined back then where

1. Testing

2. Difficulty to replace implementation

3. Requirement to track all the location where Singleton is utilized once we need to replace it.

I’d like to look into these again and re-address this ‘disease’ so to speak.

Testing (for Design Verification)

Testing is important. Maybe back then (2008) some would argue, but not today. But what this testing is for? To confirm that implementation adheres to the desired design. And, as a side effect, to have a safety net. The why not to test singleton implementation and be done? The headache with singleton is not about singleton itself, but other code/components that rely on it. Yes, these days you could use tools like Moles and Typemock, but why would you if you could DESIGN your code properly to begin with?

To me it is more about team decision on code design and collaboration. Imagine the following two scenarios:

Scenario 1: John – “I will work on the UserSession and provide you (Mike) with the contract”. Mike – “Sounds good, I’ll throw into that contract a few methods I need, when you get to implement it, lets talk”.

Scenario 2: John – “I will work on the UserSession that will do This and That”. Mike – “I will work on the component and will require UserSession, but don’t know if I need This, That, or Whatever”.

Can you spot where singletonitis thrives? Absolutely, in the team that works in silos and throws stuff over the fence. In the scenario where collaborative work is observed, need for “utility-like” classes is drastically low. After all, why would I create waste that is not used by anyone.

Other Issues

Other issues (#2,#3) are insignificant and easily solved just by following #1. Testing leads to better code design, it leads to contracts, contracts lead to design-by-contract, allowing principles like Inversion of Control (IoC) and Dependency Injection (DI). Gladly, these days, we have enough tools and knowledge among developers to recognize it (Ninject, AutoFac, Castle, Unity, etc).

So the next time you see code  where Signleton is abused – cure it.

4 Comments

  • I clicked through to the other article and it seems more like "static-itis" than "singleton-itis".



  • @Andrew,

    Yes, you are right about your observation. I summed them together and perhaps should have distinguished between the too. Reasoning behind this is the experience I got from asking people why they use static classes. Mostly reply was "in order not to create multiple instances of the object when it's not needed", which typically brought up Singleton pattern, and again, usually ended up with implementation of a Singleton to replace a static class.

    This is why I see both in the same eye. Static Gateway is a different story, yet, unfortunately, haven't seen a lot of developers leveraging that one.

  • I think I suffer a bit of singleton-itis, but not of static-itis.

    Sometimes it feels like a had a few too many things that are accessed via a static "Current" property, but when we us DI, Current will use the DI to get the instance instead of creating one itself.

    I'm not sure I found a good description (that I grokked) of Static Gateway.

    If I have an interface ILogger, I often create a class Logger with a static (factory) method "current" that returns an instance of ILogger; this class is rarely an implementation of the interface, its just a simple name to allow you to get to an actual instance.




  • @Andrew,

    I found that the need for a singleton or static class with the Current mechanism goes completely away when you use one of the modern containers. When you configure your bindings, you can declare life-time of an object. Among the options is singleton. This is very powerful as for the "consumer" code, it looks like you are getting an instance of a contract, but from the run-time perspective, it's the same instance. Also, it allows testability, as your code is injected with an object of a contract type, having no coupling to a static class or singleton.

Comments have been disabled for this content.