Singletons

Started by
39 comments, last by Way Walker 15 years, 2 months ago
OK, so what's the deal here? I understand the concept and the implementation - what I don't understand is why I am constantly being warned against The Evil Singleton. Sometimes the reason is given that it is not a truly OO approach - but if I want to implement a singleton "LawsOfPhysics" then what's not OO about that? Are there multiple instances of the laws of physics in our universe? No! So in a component-based architecture where I want my engine driven by separate component controllers, why the objection to the Singleton design pattern? It seems to fit perfectly.
Advertisement
For generalized arguments, read this. And this.

Quote:
So in a component-based architecture where I want my engine driven by separate component controllers, why the objection to the Singleton design pattern? It seems to fit perfectly.

It's actually quite the opposite: it's a horrible fit. One of the purposes of component-oriented design is to increase modularity by encapsulation of behavior and, to a degree, state. Enforcing singularity for no other reason than it 'sounds good' is the antithesis of that. Not to mention all the additional problems is causes, like difficult is isolation of components for unit testing (which components otherwise lend themselves to).

You don't need it, so don't expend the effort to do it.
This might go a few pages :)

One thing about the singleton pattern is that it says that not only is there only one LawsOfPhysics object, but that there can ONLY be one LawsOfPhysics. And if you later want to create maps that have rooms with alternate LawsOfPhysics, you have a lot of work ahead of you.

You have a lot less work if you just created a normal LawsOfPhysics class, and just passed it as a dependency to objects that need it in the first place.

Speaking of dependencies, the singleton pattern makes unit testing a huge pain. You can't inject a test version of your LawsOfPhysics class into a class you are trying to test to see how it's using LawsOfPhysics, without doing a lot of work.

Also that LawsOfPhysics is suddenly available to classes that have nothing to do with physics (like UserLogin, or Sprite). Do you really want your architecture to be that messy?

And, lets not forget static initialization and thread safety issues, language depending.

In general, the evil of using singleton comes about when the real case is not "There can only ever ever be one of these" but "I only have one of these right now, and it's easy to use a singleton whereever."
The problem with Singletons is that you never knew you needed one until you discover this "wonderful pattern". So you spend a while putting them into your project. Later on, you will realise that you have gained little or nothing in doing so. Worse - your code can start becoming more rigid and inflexible. It is harder to unit test, harder to reuse, harder to refactor, harder to reason about.

The above happened to me. It has happened to other people on these forums.

With experience I have learned that 99.999% of classes are not restricted to a single instance. I have also learned that global access is also not right for most code. That is of course in theory, I often find that a global can work as a temporary solution when hacking in a new feature. Sometimes we have to work within constraints where we can't afford to spend the time necessary to properly integrate the feature with an existing design.

Oh, and the LawsOfPhysics? What if next week you want to create a different Universe with different laws? Your thinking is warped by the assumption that the Universe itself is a Singleton.

I am afraid I disagree [smile].
What if I have an Highlander class? Can I make it a singleton?
-----------------------------------------Everyboddy need someboddy!
Quote:Original post by m0nkfish
OK, so what's the deal here? I understand the concept and the implementation - what I don't understand is why I am constantly being warned against The Evil Singleton. Sometimes the reason is given that it is not a truly OO approach - but if I want to implement a singleton "LawsOfPhysics" then what's not OO about that?


LawsOfPhysics has no local state. As such, it should be expressed using free functions.

FrameOfReferenceComponent however not only has local state, but each observer has one.

For example, while LawsOfPhysics on person orbiting earth in space shuttle and person free falling in an elevator in vacuum shaft would be simiar, to an outside observer they would be completely different. As such, laws of physics depend on individual frame of reference.

Do you realize, that while writing this message, you're moving at about 30km/s.
That this is only along Earth's orbit around Sun. Not considering for velocity of our solar system around center of galaxy. While the universe is expanding at accelerated rate.

And the best thing - the above calculation is different for each one of us, due to relativistic effects, which directly affects our perception of time, and consequently all calculations.

So unless LawsOfPhysics simulates everything with mass in our entire universe, it cannot calculate your current velocity or acceleration, or anything else.

Singletons need to know too much, so we use local instances to simplify things. And we make one universe for use on earth, one for astronauts, one for orbital mechanics, one for solar system's motion of planets, one while we're in a car, one in an elevator, one in ....
Quote:Original post by m0nkfish
Sometimes the reason is given that it is not a truly OO approach - but if I want to implement a singleton "LawsOfPhysics" then what's not OO about that? Are there multiple instances of the laws of physics in our universe? No!
Sure there can be... very large masses or masses that move at high velocity might more appropriately use a relativistic physics system. You might also have a situation where a physics system should put more emphasis on quantum physics. And, of course, in many cases a simpler Newtonian model is more appropriate.

There is no reason to think that you might not want more than one of those running in the same process.


The point of writing a class is to define a data type. There's next to no point to giving and explicit name to the type of something that is unique.

If it's important that some collection of data is created only once, wrapping it up in a Singleton simply means that you have to go out of your way to write a class definition - implicitly creating the ability to re-create the data - and then go out of your way again to take that ability away.
So much hate for poor, poor singlton.

Like the auto_ptr, it might have a use in some places and like multiple inheritance, if you want to use it, that's your decision and it's your decision whether to let other people form your opinion on your use of it. Couldn't I consider my OS a singleton? (Host OS?)

I personally don't think it's the best thing I ever heard, preferring a plain old global if I'm going to go that rout. The thing I don't like about it is the initialized on first use principle. If it's global, it's already initialized before its first use. That principle just creates annoying overly complicated getInst() crap. (And if your application is threaded, overly complicated "Double Checked Locking Pattern".)

Quote:Original post by someboddy
What if I have an Highlander class? Can I make it a singleton?

There can be two, but you shouldn't have one male and one female together.
From personal experience they are best avoided, but when wrapping a c style library in a series of classes to enhance functionality I found it difficult to dodge a singleton. The special circumstances are that first, SDL_Mixer isn't really multi-instancable because it is based on several c functions which share a single state. And the second is that to implement a play list it seems you require a basic c style function pointer. At the time I knew of no way to cast between a class specific member function and a global c function, but I believe that mem_func would probably do what I need (though when I was having this issue nobody suggested it.)

In any case, it was a decent use of a singleton because the actual concept being wrapped could not safely have several instances without each instance knowing about the other ones so we knew if it was initialized and playing etc.

Nobody suggested a better alternative in this thread:

http://www.gamedev.net/community/forums/topic.asp?topic_id=520472
_______________________"You're using a screwdriver to nail some glue to a ming vase. " -ToohrVyk

This topic is closed to new replies.

Advertisement