Skip to main content
GameDev.net gamedev.net
🔒 Locked

Using Singletons?

Started by GamerAlan Mar 19, 2003 at 11:31 AM 15 replies 650+ views
Original Post
GamerAlan
GamerAlan
When should a singleton be used? I''ve heard some say that you should use it in direct x programming for things like the screen device. Anyone have anything to say about this, or able to clarify?
-GamerAlan
stubble
stubble
Well you should use it when you only ever want one instance of the class in your whole system. For example if you have a class that manages all your textures - you only ever want to create one instance of it - otherwise you might end up loading and managing the same texture more than once. So you use the singleton pattern to make sure instances of the class can not be created - make the contructors protected - and provide a method to get hold of the single instance of your class - which is usualy a static class member.
Mage2k
Mage2k
"and provide a method to get hold of the single instance of your class - which is usualy a static class member"

This is the most important part of the singleton. It allows you to get a reference to your singleton object from ANYWHERE in your code. Say you''ve got a console object implemented as a singleton that at the very least can output text with a simple function call on that object. You can use it as a debugging tool by plugging in a few lines of code to output status, error, or any kind of information anywhere in your code without having to add a member variable for a referenct to your console in any of the classes your debugging -- it''s a "tool" that can be used anywhere without having to change any of your other code. The singleton is probably the most common design pattern I''ve seen discussed around these boards and I think that reason for this because so useful. You can modularize your whole game around singletons -- RenderDevice, MemoryManager, GameManager, TextureManager, etc... You can even subclass these -- say subclass Renderevice with DirectXDevice and OpenGLDevice and decide at runtime which kind to instantiate. Hope this gives you some ideas...

Mage
---------------------------------------------------There are 10 kinds of people in the world:Those that understand binary, and those that dont...Mage
billybob
billybob
yes, singletons are good. they allow you to fully encapsulate things that need to keep all their data toghether while keeping only one copy of it at all times. i have like 10 singletons, Renderer, ResourceManager, SoundDevice, InputDevice, Console, Log, more that i can''t remember. they made it so instead of having a global pointer to an app class, you can simply get the pointer at any time.

all i can say is that they have made a lot of stuff much easier
Shannon Barber
Shannon Barber
It depends on what you want to support, but you can have more than screen, either virtually or actually with two video cards and two monitors so it''s not a good candidate for a singleton.

Resource managers are better candidates.

The signleton is talked about a lot because it is a simple pattern and it is easy to implement a demostration (it is very hard to implement with attention to all the details). It also ''justifies'' the use of global variables which still have a valuable (if restricted) place in programming. The bad thing about the singleton pattern is that I think it promotes the overuse of globals behind a design shield (it''s not a global variable, it''s a singleton!).

The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Qw3r7yU10p!
Qw3r7yU10p!
A singleton is useful to enforce some requirement where it would be absolutely catastrophic to have more than one of something.

But with a program that needs a screen or a log file or a texture manager it''s not catastrophic to have more than one - it''s unlikely that you''ll have more than one but you''ll be able to do that without a singleton. I''ve got plenty of code where a class is only used to create one object but it isn''t a singleton. Making it a singleton would encourage me to use what is in effect a global variable. It would change the way I design things. It would make my design absolutely dependent on the fact that this thing is a singleton (even though it doesn''t need to be). If it came about that I did need two maps or two clients, for example, my design is inflexible. Singletons have far less necessity than we are allowed to believe.

I''d steer clear of them.

Pete
Qw3r7yU10p!
Qw3r7yU10p!
quote:
fup: I sort of agree with that statement, but can you demonstrate how that is a Bad Thing?


I already have.

[edited by - petewood on March 20, 2003 4:31:28 AM]
fup
fup
mmm, I don''t think you have (or maybe you have, Its very ''grey'' at this time in the morning ). I think you have only demonstrated that the improper use of singletons is a Bad Thing.

That''s just common sense to me. Are you therefore saying that inexperienced coders should stay away from singletons?

You see, I don''t think it''s good advice to tell someone to steer clear of them. I think they are very useful in their place.




ai-junkie.com
Qw3r7yU10p!
Qw3r7yU10p!
quote:
You see, I don''t think it''s good advice to tell someone to steer clear of them. I think they are very useful in their place.


One thing that C coders have difficulty with when moving to C++ is the new paradigm. Data can be private, accessed in a consistent way through member functions. Global variables are still available in C++ because, of course, C is still a core part of C++. But many efforts in object oriented design and the development of C++ have been to better encapsulate ideas, data and the way it is accessed. Global variables have only a very, very limited usefulness in the new world. The singleton pattern doesn''t do much to help people embrace cleaner modular design.

Imagine you had a singleton that was used for logging. Many classes could make liberal use of it. Every class is dependent upon the name and way of accessing that singleton. Where does that put you in terms of code reuse? If they rather were designed to know where their owner was and that owner was required to support logging functionality in some way, then you''ve got a more flexible design. You still need a log but it doesn''t have to be called theLog::Instance() or whatever you''ve decided upon. The log doesn''t need to be a singleton.

The reason I say steer clear is the same reason I''d say steer clear of goto statements. Every problem seems to be a nail using that particular hammer.
fup
fup
"Imagine you had a singleton that was used for logging. Many classes could make liberal use of it. Every class is dependent upon the name and way of accessing that singleton. Where does that put you in terms of code reuse?"

Well, strangely enough, I do have singleton class that acts as a debug console. It is a singleton because:

a) I normally only need one debug console. If I need more, it's not a problem, see below.

b) it provides exceptionally easy access for all my classes.

There's not a problem with code reuse because it is derived from two base classes. Like so:

class DebugConsole : public Singleton, public DebugBase{
...};

I don't see how this can be considered poor design.




ai-junkie.com

[edited by - fup on March 20, 2003 6:56:03 AM]
Qw3r7yU10p!
Qw3r7yU10p!
I don''t understand your code example. I''d be really interested if you could expand upon it and how it is used.
fup
fup
sorry Pete, I wrote it down incorrectly - too tired today. Let me do it again and expand upon it.


        
#define deb_con *(DebugConsole::Instance())

class DebugConsole : public Singleton<DebugConsole>, public DebugBase
{...};

void DoSomethingUseful(const SomeClass& sc)
{
deb_con << "value of SomeClass member variable is now " << sc.SomeMemberVariable() << "";
}





Argh! Those bloody code tags do my head in! How do I get blank lines between my code?




ai-junkie.com


[edited by - fup on March 20, 2003 7:19:23 AM]

[edited by - fup on March 20, 2003 7:20:26 AM]
Qw3r7yU10p!
Qw3r7yU10p!
wiki, as always, has something to say.

Especially see Kent Beck''s entry near the bottom
fup
fup
I still don''t see it Pete. Beck obviously made the wrong choice when he used a singleton implementation of his CurrencyExchange. (From the example he gives it seems blindingly obvious (from an observers standpoint, reading his retrospective text - I''m not saying I wouldn''t make the same mistake ) that a singleton was the wrong decision.)

I think, in the end, this may just be a matter of taste.




ai-junkie.com

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.