Search this blog

24 April, 2008

Singletons: the new superglue

Singleton is the most common, if not the only, design pattern I see in my game programming work. It's so popular because it provides a nice encapsulation of a nasty concept: global, shared state.

But everyone knows that global, shared state is a bad thing, that was a bad thing to have even when no one cared about thread safety, so we just wrapped them into that nice design pattern...
Global state makes two classes communicate if they both happen to use it, no more if you explicitly design the dependency. Anyone that can see it can access it, both for reading and writing, only a very few number of system components should be accesses in such a broad way.

Generally speaking, I don't like patterns too much. They provide you just the right amount of knowledge you need to make a bad design, thinking it's good. The worst errors I've ever seen do not came from no knowledge, but from having just the the right amount of it, too small to really understand what you're doing, but enough to think you did. That amount of knowledge, is evil.

Note: This a very nice article on why static variables are bad in general. This of course applies even more to global ones and thus, to singletons.
Note: Another very good article against singletons (well actually, better than this one) is this one.


Anonymous said...

Yes singletons are Evil.
But game programming is often ugly programming, mostly because users need more efficient code, forgetting about bugs.
I'd say singletons are good for quick'n'dirty code like prototyping

FieldsOfCarp said...

Using singletons as globals is just plain wrong and on top of that inefficient. If you use a pure global the assembly doesn't have to check every time if the static has been initialised. I once read an interesting article by Herb Sutter in CUJ on "singleton pattern abuse". Unfortunately game programmers (not all of them) including me often can't be bothered to design software beyond their nose and establish clear ownership rules so globals, pardon, singletons will be around for some time.

gpakosz said...

hmm to me, Singletons are more about controlling the instantiation phase of the object than about any need for a global shared state

the cherry on the cake is that you perform the initialization lazily the first time the object is actually needed

(sorry if i come late in the discussion :) )

DEADC0DE said...

if so you should implement the pattern with a non-static instance getter, if you do singletons in that way, you'll quickly notice that they are way less "useful" and way less used... In practice, the singleton is, in my experience, always used as a shared state, with a fancy name.

DEADC0DE said...

p.s. the lazy initialization thing is also a "bad" thing of that pattern, the pattern should be about having a single instance, it turns out to be about having shared state instead, plus it says something about initialization, making it (without any need) lazy... That's an extra thing that should not be in the pattern, it's not necessary.

In many cases people want to have an exact control of when they initialize and destroy such objects, so they simply implement singleton without lazyness.