3 Replies - 735 Views - Last Post: 22 June 2012 - 03:54 PM Rate Topic: -----

#1 nunc  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 131
  • Joined: 20-November 11

Singletons - Are they really bad?

Posted 21 June 2012 - 01:39 PM

I'm trying to expose myself to some more advanced topics of C++ as well as using makefiles to compile projects and using the SDL library to expose myself to linking in outside sources.

With all of this I'm trying to create a simple game in c++ to utilize all these topics. I've looked around for game architecture, and it seemed that using states, with singletons was the widely accepted answer. But I've run across problems using singletons when trying to access information from them and I don't think I know enough c++ to debug the problems.

So i've come to ask, are Singletons a habit I should avoid creating? And if so, is there an alternative to creating game states that could hopefully replace singletons?

Is This A Good Question/Topic? 0
  • +

Replies To: Singletons - Are they really bad?

#2 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Singletons - Are they really bad?

Posted 21 June 2012 - 02:13 PM

Singeltons are basically glorified global variables. They often have problems with modified state, and are often plagued with race conditions.

That said. There is really nothing truly evil about them especially if used correctly. Always assume concurrent access (even if you don't think it should ever happen in your single threaded application). Modern frameworks often sneak threads in there for you! This means Mutexes.

I use singletons as gateways to resources such as allocators, thread pools, logging, object factories etc. where the singleton preforms some simple act. Remember the more state you have the harder it is to control race conditions and deadlocks! Keep it SIMPLE!

But to the best of my knowledge they are not evil - but they can be a little hard to deal with.
Was This Post Helpful? 1
  • +
  • -

#3 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: Singletons - Are they really bad?

Posted 21 June 2012 - 02:13 PM

game states don't have to be singletons. I'm not a very big fan of singletons however; they're just glorified global variables with the added guarantee that only 1 instance will ever exist but that's just personal preference I guess. I think allowing for multiple instances is more manageable.

Quote

Singeltons are basically glorified global variables.

Jinx!

This post has been edited by ishkabible: 21 June 2012 - 02:14 PM

Was This Post Helpful? 1
  • +
  • -

#4 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 856
  • View blog
  • Posts: 2,339
  • Joined: 20-August 07

Re: Singletons - Are they really bad?

Posted 22 June 2012 - 03:54 PM

In my opinion, singletons are unnecessary 99% of the time I see them used (Nick has pretty much covered the 1% of good/useful singletons).

Single-instance objects are indeed a fact of software development; you generally can't escape them because often you'll find problem domains where only one of a particular type of entity will ever exists - but that doesn't mean a single-instance object needs to be a singleton, nor does it mean that a singleton is the best way to model that object.

There are several problems with the Singleton design pattern which I can think of:

- they are global variables - if they store a state which can be modified from any part of your program, then you expose yourself to the same kind of complexity problems associated with global variables. If the singleton has state which is modified during the lifetime of the program, then the chance of you accidentally introducing unexpected behaviour due to that global variable's inconsistent state is massively increased (And might take you a while to figure out the problem; depending on how much complexity you've got, it might not be easy to fix either)

- accessing a singleton from multiple threads is a historically tricky area which programmers nearly always seem to forget/ignore until it bites them really hard. Over the years, people have come up with idioms and patterns to mitigate problems, but they're all a little bit ugly IMO (I don't particularly like having to shove mutex lock statements everywhere, but that's pretty much what you're stuck with)

- You cannot unit test code which depends on a singleton without importing that singleton into your unit test. This is a problem since it flies in the face of everything that unit testing is designed to achieve - i.e. complete decoupling of a bit of code from its dependencies in order to test that code on its own; As soon as that code has hard-wired dependencies, you increase the chance of your unit tests becoming useless (What if the singleton changes but the unit tested code doesn't? are the unit tests still valid?). If you follow a unit-testing driven approach to programming, then you need to avoid singletons like the plague.
Unit testing is increasingly being regarded as a good thing; so anything which obstructs unit testing could arguably be labelled 'evil' for that reason.

- It's harder to reuse code which depends on a singleton. if you adhere to good software engineering practices, then hopefully you'll end up with plenty of self-contained modules which can be very easily picked up and reused in another project without any extra 'fluff'. Dependency on a singleton means that in order to reuse that code, you either need to rewrite it to remove the singleton (And then re-test it!), or you need to bring the singleton along (But wait, you only wanted the class on its own and not its dependencies..? too late!)

- You can't (and shouldn't) extend a singleton. You're creating a class which will only ever have one object; if your requirements change later down the line and you discover that you need more than one, you're looking at ripping the whole thing out and rewriting stuff from scratch. No opportunity to override bits of the code with inheritance, and walking down the disasterous path of "lets expand the singleton interface/add extra variables to do what we need" is a recipe for painful headaches later on. Again, it partly flies in the face of software engineering principles about decoupling/reusability/etc (Although admittedly a singleton usually does meet the most important one which is "Keep It Super Simple")


With all that said, NickDMax has hit the nail on the head; the real enemy is a singleton whose state affects the logic of your program. Stateless singletons containing pure functions (functions with no side effects) are unlikely to be a huge problem, and the examples which Nick provided (diagnostic logging etc) could all fit quite happily in standalone mostly-stateless classes.


As I mentioned before, single instance (stateful) objects are also a fact-of-life, and they don't necessarily need to be singletons; they can just as easily be objects which are created near the top level of your application (i.e. inside main() or somewhere nearby) and passed around by-reference to whichever other objects/classes need to use them.

For example, in some kind of simulation, you might have a "World" object at your application root level which stores the state of your simulation's world - chances are that other entities in your program are going to need to interact with it and change its state or listen to its events. For objects like this, passing references around would be a reasonable solution, and also using some kind of 'event subscription' design pattern (using function objects, lambdas, std::function, etc) might also be preferable instead of creating it as a singleton.

Hopefully you can minimise the exposure in your program for these kinds of far-reaching stateful objects, but even if you can't, creating a singleton is unlikely to actually make it better.
Was This Post Helpful? 3
  • +
  • -

Page 1 of 1