When to use and not to use singletons

Started by
51 comments, last by AnthonyG 16 years, 11 months ago
Quote:Original post by ToohrVyk
Quote:Original post by skittleo
Point taken. However, they both solve the same types of problems. Why is one implementation inherently worse than the other? The end result is the same: a global point of access to some functionality or state.


The ideal field of application of a singleton is when the entire code uses a Base class, and there is a Derived class which inherits from Base and which cannot possibly be implemented to allow more than one instance. In that case, you make Derived a singleton. Almost nobody will use the global access point, and everyone will use a non-global Base reference to the singleton instance instead.

If you don't need the singleton to act as an object (through inheritance), standalone functions provide the same benefits without the hassle.


Aha. I appreciate the example.

Since singletons are just a concept, a language could in theory make implementation of them extremely simple. Say something like:

singleton class DerivedSingleton from Base
{
DoSomething() {}
}

DerivedSingleton::DoSomething();
Base* obj = DerivedSingleton;

Right? In which case we might be saying that static classes are worthless since they offer no difference in functionality and no option to derive from a base class. To me it seems that singletons in concept are fine, but their implementations are usually messy so they are regarded as worthless.
....[size="1"]Brent Gunning
Advertisement
Quote:Original post by Spoonbender
Quote:Original post by skittleo
You can still have multiple mice or multiple graphics devices. All it requires is reimplementing the underlying technology which isn't difficult. You will have to do that anyway if you wanted to use a non-x360 gamepad for instance.

Care to explain how, for a non-XNA user? (If we were to assume these classes really were singletons)

How would you make it so I could use two mice in my game, if the mouse input class is a singleton?


Sure. First, as Promit corrected, they're not actually singletons. They're static classes. Sorry about the confusion.

To have two mice you would reimplement the underlying DirectX technology in a new class. I used the example of gamepads since XNA only offers one interface for gamepads that limits you to XInput devices.
....[size="1"]Brent Gunning
Quote:Original post by skittleo
But since singletons are just a concept, a language could in theory make implementation of them extremely simple.


I tend to say that if you make singletons too easy to use, people will start using them when they're not required. I know it's silly to shoehorn people into being good software engineers, but still.

Quote:Right? In which case we might be saying that static classes are worthless since they offer no difference in functionality and no option to derive from a base class. To me it seems that singletons in concept are fine, but their implementations are usually messy so they are regarded as worthless.


Ideally, global entities are separated into two categories: global instances (the entities that have state) and free-standing functions (the entities that have no state). Static classes are often used as a fill-in for free-standing functions, when the language does not support the latter (Java and C#, for instance), and singletons (which are a form of global instance) are not a valid replacement.
Quote:
Why is one implementation inherently worse than the other? The end result is the same: a global point of access to some functionality or state.

If they don't hold state, and are more procedurally-oriented (where state, held by the user, is supplied to them), they're not singletons -- global access alone is not enough to be a singleton, nor is it always a bad thing (logging should usually have some kind of global accessibility, for example, but need not be a singleton).

In one of the my later posts on the Rate My Engine thread I talked briefly about static classes, implementation detail versus conceptual design constraints, and whether or not static classes are always singletons. Basically, they start to get into a hazy grey area -- especially if they hold state.

The XNA stuff holds state, which starts to push them away from procedural free functions and more towards singletons. It gets murky... I don't particularly enjoy the design either, and I don't think it its a good, scalable one.

Quote:
To me it seems that singletons in concept are fine, but their implementations are usually messy so they are regarded as worthless.

It's the other way around. Singletons have a very, very specific usage case that is very, very rarely required. They end up getting used because they're really easy to use as a crutch, so the developer doesn't have to think too hard about the atrocities they're committing by (for example) requiring access to the graphics subsystem from deep within the sound subsystem. They bleed dependancy and assumption all over the codebase, and artificially restrict future maintainability (enforcing the programmer to have only one, when any sane programmer could reasonably restrain himself from making more than one, and thus avoid the assumption of "only one.") and extensibility.

However, a lot of people, failing to realize this (usually people who say singletons are bad purely on hearsay) will parade around silly implementation-specific "problems" like the static initialization order problem in C++, or the "overhead" of the accessor methods, et cetera, in an effort to devalue the design pattern. They're not wrong, usually -- the design pattern is probably being misused -- but the implementation detail is not the flaw; the effect the concepts have on the design of the rest of your code is.

I have to rush to a meeting now, I hope the above makes some kind of sense since I don't have time to review it.
Quote:Original post by ToohrVyk
Static classes are often used as a fill-in for free-standing functions, when the language does not support the latter (Java and C#, for instance), and singletons (which are a form of global instance) are not a valid replacement.


Gotcha.

What about static classes with static members though? Wouldn't they operate the same as a singleton since both can maintain state?

Edit: jpetrie's post was in regards to this. You can ignore.
....[size="1"]Brent Gunning
Quote:Original post by jpetrie
The XNA stuff holds state, which starts to push them away from procedural free functions and more towards singletons. It gets murky... I don't particularly enjoy the design either, and I don't think it its a good, scalable one.


But don't you think for XNA's purpose (being easy to use, easy to learn, quick prototyping) static classes with state (... singletons?) work fine? A beginner learning to program in C# and create games can easily remember Mouse.X but they might not as easily remember or understand InputDevices.Mice[0].X. I'm just trying to make the point that sometimes singletons are OK.
....[size="1"]Brent Gunning
Quote:Original post by jpetrie
However, a lot of people, failing to realize this (usually people who say singletons are bad purely on hearsay) will parade around silly implementation-specific "problems" like the static initialization order problem in C++, or the "overhead" of the accessor methods, et cetera, in an effort to devalue the design pattern.
Don't forget threading and double checked locking issues related to singletons. The amount of writing about that stuff is unbelievable.

I compiled a a list of singleton related links, in case anyone is curious.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Quote:Original post by skittleo
Quote:Original post by jpetrie
The XNA stuff holds state, which starts to push them away from procedural free functions and more towards singletons. It gets murky... I don't particularly enjoy the design either, and I don't think it its a good, scalable one.


But don't you think for XNA's purpose (being easy to use, easy to learn, quick prototyping) static classes with state (... singletons?) work fine? A beginner learning to program in C# and create games can easily remember Mouse.X but they might not as easily remember or understand InputDevices.Mice[0].X. I'm just trying to make the point that sometimes singletons are OK.


Culture momentum.

Singletons have been shown and proven in many cases to be a bad practice. But this happened reasonably recently.

If you have a choice, use the "proper" design. But if you're stuck between legacy concepts, background compatibility, platform specific static nature of architecture, in addition to considering programming nothing but a 9-5 job, then you'll use singletons.

Just because it's still present doesn't invalidate its flaws. Look at the stuff still taught at universities. How much of it could be considered heresy these days (if you don't know what I'm talking about consider yourself lucky).

In other engineering branches culture changes when people die. It takes 100+ in a single accident, or more than insurance is willing to cover on yearly basis. Software doesn't kill anyone. So things change slowly (yet still blazingly fast compared to other engineering techniques).

This isn't about: "Look ma, Johnny's doing it, so I can too"

When asking when or how to use a certain design practice, look at design practices at your disposal, then evaluate them for their own merits and flaws. Copying concepts because someone else used them is hugely flawed.

This is the wikipedia syndrome. "I read it on wikipedia, so I'm an expert on topic". Singletons have their perfectly valid use, just like anything else. But if you look at examples and tutorials from past 10 years, almost all of them use static constructs.

Why?

These documents aren't reviewed or revised. Implications of the design aren't documented. And those who learn from them learn wrong concepts.

It was said long ago that BASIC ruined whole generations of programmers. Was BASIC bad? No. It was so easy people got into programming - but never realized that the concepts they took for granted were flawed, unscalable and useless in real world.

Singletons are today's BASIC.

Can VB be useful? Today, with today's .Net versions, with all the support APIs and VB for Applications, yes. But always remember what VB is. Coming into any serious software development with "VB experience" won't give you much crediblity.

About XNA: yes, it's attractive, it will allow people to make games.

But some of them will know nothing but. And then they'll have a rough encounter trying to get into either big-shot game design, or other software development positions. Those that do not understand the background, will be in for a very rough ride - not because they couldn't find a job - but because they'll be the COBOL programmers of yesteryear.

Knowing one framework, no matter how well, but without understanding the concepts behind it (even if flawed), is a sure way to obsoletion.
Quote:
I'm just trying to make the point that sometimes singletons are OK.

I struggle with this. On one hand, I haver never in my years of programming been convinced that a singleton was a good solution (assuming you go back and retroactively apply what I know now to my youth -- as a budding C++ programming twelve or so years ago I fell into the singleton trap many times). In all cases it is, if nothing, artificially and prematurely limiting or a sign of laziness on the programmer.

On the other hand, I firmly believe that there are no hard-and-fast never-say-never rules in software design and development, which prevents me from being able to say "never use singletons" with Promit's conviction, which I am jealous of.

I'm trying to fix this by convincing myself that the exception to do-not-use-singletons rule is when the singletons are already firmly entrenched, and your project is over budget and overdue, and the cost to refactor the spiderweb of dependencies and other nastiness would kill your company. But I'm not quite there yet.

I don't think XNA's singleton or singleton-like classes are good, because they'll provide a flawed foundation for neophytes and a thing they point to and say, "well if singletons are so bad how come XNA uses them?"

This is bad.
Quote:Original post by jpetrie
I'm trying to fix this by convincing myself that the exception to do-not-use-singletons rule is when the singletons are already firmly entrenched, and your project is over budget and overdue, and the cost to refactor the spiderweb of dependencies and other nastiness would kill your company.
The problem with that, of course, is it means you've already broken the rule. So it's no surprise that maybe the rule doesn't apply to you.

The problem is that all the situations where the singleton starts to make sense are basically major breakdowns in structure. For example, the static class thing breaks down -- in C++ -- when handling module boundaries, because each module gets its own copy. Singletons become a "solution" there, except the design is already broken, because you're sharing global objects across modules.

So my closest cop out is "the singleton can occasionally make sense, but only when you screwed up big time somewhere else".
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.

This topic is closed to new replies.

Advertisement