Sign in to follow this  
Will F

Singleton design pattern

Recommended Posts

Will F    1069
I've got a few questions about singletons, mostly whether or not I should be using them. but first a bit of relevant info about my project (hopefully this makes sense) I'm working on a 2D graphical roguelike in c++ and SDL and this is what the structure of my program looks like: main function Essentially only creates an instance of a class called CGameEngine CGameEngine has a pointer to an base class CGameState which I use polymorphism to store a gamestate CGameEngine runs the event loop and passes any relevant events onto the game state, or deletes the current game state and creates a new one if it receives a gamestate change event (for instance, when you select new game from the title screen state, it pushes a newgame event onto the event queue CGameStateTitleScreen - derived from CGameState Doesn't doo much, shows some animation, lets the player start a new game or load a game, or quit CGameStateRunning Where the action is Among other things, it has pointers to a sprite manager and a texture manager, both of which are created when the class is initialized. The sprite manager contains sprites, each of which contain a pointer to the texture manager (which stores the sprite's image). So basically my question boils down to this, is this a good overall design? Should I instead be implementing the texture manager as a singleton? My understanding is that singletons are useful for providing global access to a manager and ensuring that only one instance of the manager class exists. But since I create the manager once and keep a pointer to it in CGameStateRunning (so I don't have to worry about multiple instances), which then passes that pointer to sprites when they are created .. what would be the advantage of using the texture manager as a singleton (other than a slightly smaller memory footprint because the sprites don't need pointers to it) rather than the way i'm doing it? Also could someone point out a real world example of where singletons are useful? I'm generally wary of using anything that is available at global scope, but i'm trying to make sure I understand the concepts properly.

Share this post


Link to post
Share on other sites
Will F    1069
Quote:
Original post by mgarriss
you might be interested in this.


Ok, so the answer to my question is in the link in the Abuse of singletons section?
"Do we really need the graphics renderer to be global? Can it be a member variable of an Application object instead?"

So what i'm doing is fine?

Still I wouldn't mind some feedback on when using a singleton is a good idea. I'm pretty sure I understand the concept of a singleton, but i'm still not sure when and where I should use a singleton if another option exists (except maybe for increasing code readibility).

Share this post


Link to post
Share on other sites
mgarriss    154
i think that singleton can be very useful. for example, your program loads a config file that many different parts of your code need to access. one solution would be to pass around a ref or pointer to your config object everywhere it's needed. the other option is to have it available at global scope. this is fine IMHO because there should only ever be one instance of this object and it also cleans up your code. you can eliminate having a config pointer in all the classes that need it (which could be a lot) and you don't have to pass it into every constructor.

_ugly

Share this post


Link to post
Share on other sites
Will F    1069
Quote:
Original post by mgarriss
i think that singleton can be very useful. for example, your program loads a config file that many different parts of your code need to access. one solution would be to pass around a ref or pointer to your config object everywhere it's needed. the other option is to have it available at global scope. this is fine IMHO because there should only ever be one instance of this object and it also cleans up your code. you can eliminate having a config pointer in all the classes that need it (which could be a lot) and you don't have to pass it into every constructor.

_ugly


So in my case it would be useful in that I'd have less pointers passed into each sprite constructor (lower memory usage), but at the cost of an additional function call to get an instance of it every time I need to use it?

I think I just have an irrational fear of putting things at global scope (which I need to get over - but without overusing it).

[Edited by - Will F on June 9, 2005 7:15:54 PM]

Share this post


Link to post
Share on other sites
Deyja    920
Singeltons are only slightly better than global objects. You only need a singleton when you need to control the order of creation and destruction of global objects. Normally, the order of the creation/destruction of global variables is undefined. If some global depends on another global being created first, you will need to ensure that it is. The singleton pattern is a way to do this. This is an example of the singleton pattern:


int& GetGlobalInt() {
static int i = 5;
return i;
}


No matter what code wants to use GlobalInt - even the constructor of a global object - it will be properly initialized to 5 before it is used. If you had just written


int GlobalInt = 5;


with a corrosponding extern int GlobalInt in a header, the value of GlobalInt would remain undefined until after all global objects are initialized - afterall, it might just be initialized last.

This, and ordered destruction, are, IMHO, the only reasons to use a singleton over a simple global variable.

Share this post


Link to post
Share on other sites
mgarriss    154
two other important cases where singleton makes more sense then just a plain global are:

a) when we need to ask the world how to construct the singleton. for example, asking a user where the config file is.

b) when a certain path through the code does not require use the singleton. for example, maybe we don't need to load the config file this time.

Share this post


Link to post
Share on other sites
Will F    1069
Quote:
This, and ordered destruction, are, IMHO, the only reasons to use a singleton over a simple global variable.


Ok thanks, I think I have a better understanding of them now. I just keep seeing singletons mentioned in things i've been reading. I thought I understood how they worked (basically a slightly better way to use global objects but I was worried that I might be missing something.

I still don't understand why you would use them unless you absolutely had to. I tend to think of global scope as "evil" - don't use it unless you need to or have a good reason to do so (or else next thing you know you'll end up with far too many globals - I generally use few if any globals in my projects).

Since my way also controls the order of construction and destruction, I think i'll stick with the method I described above for the texture manager on my project, I can live with the memory overhead of roughly 40 pointers to the manager.

Share this post


Link to post
Share on other sites
petewood    819
Quote:
Original post by mgarriss
i think that singleton can be very useful. for example, your program loads a config file that many different parts of your code need to access. one solution would be to pass around a ref or pointer to your config object everywhere it's needed. the other option is to have it available at global scope. this is fine IMHO because there should only ever be one instance of this object and it also cleans up your code. you can eliminate having a config pointer in all the classes that need it (which could be a lot) and you don't have to pass it into every constructor.


I'm not sure I'm understanding you. Are you saying these are the only design options you have available to you?

I would have thought that for any subsystem it was reasonable to have a specific configuration object, with just enough info in it to configure that system. It also seems reasonable for an object to know that it wants to create a subsystem and to pass that sub-configuration to a new object in a constructor.

A system using a singleton would mean that, for example, the renderer would know how the joystick was configured and the player avatar would know how the sound system was setup. Even if you are disciplined and don't make use of any of this knowledge, there is a principle in design which crops up in many different terms but is essentially the same, that of only talking to your immediate neighbours, of layering, of the separation of concerns.

This use of singleton sends up a warning flare for me.

Share this post


Link to post
Share on other sites
mgarriss    154
Quote:
Original post by petewood
Quote:
Original post by mgarriss
i think that singleton can be very useful. for example, your program loads a config file that many different parts of your code need to access. one solution would be to pass around a ref or pointer to your config object everywhere it's needed. the other option is to have it available at global scope. this is fine IMHO because there should only ever be one instance of this object and it also cleans up your code. you can eliminate having a config pointer in all the classes that need it (which could be a lot) and you don't have to pass it into every constructor.


I'm not sure I'm understanding you. Are you saying these are the only design options you have available to you?

I would have thought that for any subsystem it was reasonable to have a specific configuration object, with just enough info in it to configure that system. It also seems reasonable for an object to know that it wants to create a subsystem and to pass that sub-configuration to a new object in a constructor.

A system using a singleton would mean that, for example, the renderer would know how the joystick was configured and the player avatar would know how the sound system was setup. Even if you are disciplined and don't make use of any of this knowledge, there is a principle in design which crops up in many different terms but is essentially the same, that of only talking to your immediate neighbours, of layering, of the separation of concerns.

This use of singleton sends up a warning flare for me.

a config object may not have been the best example. but it's still interesting when you have a config object that can change at runtime (i.e. a reconfigure without restarting the program). i see singletons as useful for any resource that many parts of the system may need to use. another example may be a logging system.

Share this post


Link to post
Share on other sites
Conner McCloud    1135
Quote:
Original post by _the_phantom_
For those considering singtletons you should probably read the following three journal entries by the great Washu;
clicky 1
clicky 2
clicky 3

I don't think that's what you meant to post. Here's my attempt
Why are you infected with Singletonitis?
Singletonitis, Part 2
Singletonitis, Part 3

They're an interesting read, thanks for pointing them out.

CM

Share this post


Link to post
Share on other sites
Seriema    634
I've seen one good use of singleton, a texture manager. No matter if you're running two or more "game applications" within your game app or whatever. The computer still only needs to load a texture once, there's no point in two instances (running in the same .exe though) to have the same texture loaded twice into memory.

Although, this would probably be better implemented as a Monostate behind some actual object such as the Render Core (renderCore::getTexture(name) would be a nice place to hide it). Of course, this would only be usefull if you have 2+ RenderCore's running at the same time.

*me goes reading Washus journal*

ps. oddly how I just ranted about singletons before seeing this post... ds.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this