Wednesday, 30 July 2008

To singleton or not to singleton

A colleague (Jacques or David L.?) pointed out an article explaining why singletons are evil, and they should be avoided:

http://blogs.msdn.com/scottdensmore/...27.aspx

Although there are some valuable points coming from experience, I can't say that I totally agree with it. This article makes a better representing of my thoughts:

http://www.ddj.com/cpp/184401625

I'll try to come up with my own explanations as objections :)

1. "Singletons are almost like globals, and since globals are bad, singletons are bad."

In my opinion, the first reason why global variables are bad is that you have almost no control over initialization or modification operations over them. There's a global variable in the global scope who knows where it's coming from, who and when initialized it, does it contain valid information... Second, probably the strongest objection to globals is, when you keep writing code depending on globals, those globals sit in the centre of your design with an extremely tightly coupled fashion, Turning your whole code domain into a single 'deadly complex finite state machine'. [Not mentioning about debugging problems of such a code]

But they don't apply for singletons. You know when a singleton is initialized (lazy to death, if you like), and that the class initializes itself. It still only publishes an appropriate interface with read-only members, etc.

2. "Code that depends on a singleton is hard to unit-test."

Well, it's completely right. But it's not the fault of singleton objects, It's weakness of your testing framework. If you really want your objects to be stateless at the beginning, then I'm sorry but you have to well-write those Setup() and TearDown() methods, even it comes with a cost of dynamically loading and unloading many dlls.

3. "Don't use singletons, write a 'factory method'".

Well, this is possibly the most ridiculous one. A factory method, if it doesn't incorporate 'static' concept, can't do what a singleton does. And if it incorporates the static concept, it actually IS a singleton.

4. "Singletons screw polymorphism."

I don't have any objection to this. It's completely true. They do screw polymorphism. But you may have deeper problems with your design if you think an object 'will have only one instance' and there are going to be more than one objects subclassing the previous one. I better seal the singleton with a 'sealed' or 'final' keyword and take a French leave.

My objections don't eliminate the fact that singletons are abused. But I think the answer to this singleton deal is old and classic enough not to make me seem smart: "It depends.". It's always better to pass a reference to your single-instanced-object when you can, for many reasons like clear representation of coupling. But there will always be some cases you'll end up with ridiculously complex solutions just to avoid an innocent sweet singleton. It's a trade-off decision.

3 comments:

özgür said...

hey, what's wrong about ensuring to have just one object, for example if that object deals with database operations.
i don't want to connect to the database every time i need a query, and i also don't want to pass my connection object everywhere.

Görkem PAÇACI said...

Well, I think we agree, right?

On the other hand, be aware not to place your connection on a static context in asp.net. All worker processes IIS produces will use the same compiled dll of your code, and it'll have only one instance of your connection. It's absolutely not a good idea to handle all requests with a single connection object. It's better to create a new connection (with the same connection string) in each request(or maybe session, depending on the case), and leave the rest to the connection pooling system.

Helloween said...

Conclusion:
Use Singleton where they should be used :)