Sign in to follow this  
Pxtl

Am I crazy? what is a singleton?

Recommended Posts

I've been looking into design patterns, particularly after experimenting with Python and Ruby and the bizarre lexical constructs you can do in them. The thing I notice reading is this: I can't figure out what a Singleton does. I mean, everyone says the same thing: if you only need one copy of the object, then this is how you do it. But the exact nature of this is strange: sometimes people show it as a shared object - that is, you have one object shared between all objects, and you use the class to access it. In that case, isn't this the same as a class full of static members, effectively a big global? Some people end up just using it as shorthand - functionally its the same as a regular static object, except using the constructor instead of an "initialize" function and a destructor instead of a "finalize" function. For example, launching a core system like the graphics library could be done like this. Add in refcounting and you've got a good system for a single shared service. But as I've seen it, that's not a really popular approach, so I remain confused. The final approach is access control - you need only one system at a time to access the mouse, so you say that they have to "construct" the mouse, and other objects cannot do that while it is in existance. Essentially this makes the singleton a hybrid of the "protected" types common in multithreading and a memory-saving and quick-wiping scheme that throws the data out while not in use. So which of these is the actual purpose of the Singleton? [Edited by - Magmai Kai Holmlor on July 6, 2004 11:07:29 PM]

Share this post


Link to post
Share on other sites
A singleton is defined by the GoF as "Ensure a class only has one instance, and provide a global point of access to it".

Anything else is just implementation details, there are 101 ways to implement it.

Share this post


Link to post
Share on other sites
Okay, some of the documents I read didn't mention a global point of access to it. That nixes the Singleton as a protection scheme for mutual exclusion. In that case, it is really just a global static class with a constructor and a destructor isnt it?

I mean, couldn't it be replaced with a functional module that has a "initialize" and "finalize" function?

Share this post


Link to post
Share on other sites

"A singleton is a global object for which only one instance exists in the whole application. Most applications, and definitely all games, need global objects that must be visible from many different classes and scopes. A texture manager, the joystick controller object, and even the player class are all singletons. We need to have them visible at all times, and we only want to store one of these in memory. "

Core Techniques and Algorithms in Game Programming
By Daniel Sánchez-Crespo Dalmau


but wait, there's more

Thus, the solution to the singleton problem is different from those explained earlier. It starts by declaring a class that has only one public method, which will be used to request an instance of the singleton. All instances actually point at the same structure, so this request call must create the singleton for the first call and just return pointers to it in subsequent calls. Thus, the constructor is a protected member, and all outside accesses to the class are done by the instance request call.

Here is the code for a sample singleton:


class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};

Singleton* Singleton::_instance = 0;

Singleton* Singleton::Instance () {
if (_instance == 0)
{
instance = new Singleton;
}
return _instance;
}


Any class requiring access to the singleton will just create one singleton variable (which will be different in each case).But all these variables will end up pointing at the same, unique object in memory.

Share this post


Link to post
Share on other sites
How is this a "pattern" - isn't it just global? And yet so much I find describes the Singleton as "don't use evil globals". It seems to be just a really elaborate way of writing a global but pretending its an object to me.

Share this post


Link to post
Share on other sites
Singletons are not replacements for globals. The only thing they have in common is the global point of access. The singleton pattern ensures that there is only one instance of a class, a global does not do this.

Share this post


Link to post
Share on other sites
Quote:

Singletons are not replacements for globals. The only thing they have in common is the global point of access.

No, but people still use them as a replacement for globals. Singletons are way overused; infact, in my entire 2 years I've been programming I've never seen a situation where a singleton had to be used instead of just passing around the instance of the class.

Share this post


Link to post
Share on other sites
A singleton never has to be used, but when you have a class for which only one instance can logically exist it is vastly simpler to use a singleton than to pass it around the block to everything.

Of course this technique can be abused just like any other, its merely a matter of making good design decisions.

Share this post


Link to post
Share on other sites
Quote:
Original post by Jingo
Singletons are not replacements for globals. The only thing they have in common is the global point of access. The singleton pattern ensures that there is only one instance of a class, a global does not do this.


I could be completely misunderstanding, but when I fill in the missing words and substitute the backreferences in "a global does not do this", I get "using a global variable does not ensure that there is only one instance of the global variable."

Uhh...

The only reasons I can think of why any 'pattern' would ever be needed are:

- to solve static order of initialization problems. (Which, in Java at least, are a Can't Happen(TM), unless you have a cyclic dependency that would need some other resolution strategy *anyway*. C++ certainly allows the possibility though.)

- to allow runtime polymorphism in order to select some singleton subclass to treat as "the instance" (I am told this gets used for abstracting away rendering layers when you - somehow! - don't know until runtime which graphics API you're going to use.)

But this seems bug-prone (suppose you switch during execution for some reason - admittedly not likely with the graphics API example - and other classes have cached references to the old singleton?), and the same effect can be had with static classes just as easily - just add appropriate extra state, and consult it when deciding what action to take. If necessary, use it to dispatch to other static classes.

Of course, this starts to smell in Java (since you're implementing your own dispatch mechanism, and don't get the luxury of pointer lookup of the classes - unless you use reflection - so that you're stuck with else-if's) but it seems like it would be quite idiomatic in Python, say (where classes and functions are already objects) or heck, in C++ (where your static class could manage itself rather nicely by swapping function pointers around).

Edit:

Quote:
Original post by Illumini
A singleton never has to be used, but when you have a class for which only one instance can logically exist it is vastly simpler to use a singleton than to pass it around the block to everything.


Why pass it around if you can get away with not even creating it? :)

Share this post


Link to post
Share on other sites
I really only use singletons for lazy initialization of things. If I have to construct a message routing window, I won't actually do so unless I must. Singleton does make that easier.

But yes, most people throw a singleton in and mistakenly think that since it is a design pattern it is somehow cleaner. Bzzt, a global is still a global by any other name.

And I prefer monostate to singleton anyway.

Share this post


Link to post
Share on other sites
The only argument for singletons that I can agree with is that if you make something static you can't control exactly how and when it's created (at least I've heard this argument several times).

Singletons is something that popped up in a "famous" game-programming book and everybody wanted to be cool and started to use it. As I see it singletons can make global hell a bit colder but still if you have an oo design then you're fine anyway....

Share this post


Link to post
Share on other sites
I think antareus stated the right reason to use it: sometimes you need either 0 or 1 instances of a particular class, and always using a static Singleton.get method to access the object lets you not worry about wheteher and when it will be initialized. At least, that's all I've seen in singleton implementations - the only extra trick is to make them thread-safe; there are apparently a dozen ways to do this wrong in Java, so every Java site writes an article about how to properly use singletons. You only need to use this for objects which are expensive to instantiate and which are not used every time the program is run. For example, a connection to a database, a script interpreter, or a large lookup table.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
- to solve static order of initialization problems. (Which, in Java at least, are a Can't Happen(TM), unless you have a cyclic dependency that would need some other resolution strategy *anyway*. C++ certainly allows the possibility though.)


Singleton's in C++ cause far more initialization problems than they solve.

Quote:

- to allow runtime polymorphism in order to select some singleton subclass to treat as "the instance" (I am told this gets used for abstracting away rendering layers when you - somehow! - don't know until runtime which graphics API you're going to use.)


Bingo! Regard cin & cout as legacy examples

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Magmai Kai Holmlor
Quote:
Original post by Zahlman
- to solve static order of initialization problems. (Which, in Java at least, are a Can't Happen(TM), unless you have a cyclic dependency that would need some other resolution strategy *anyway*. C++ certainly allows the possibility though.)


Singleton's in C++ cause far more initialization problems than they solve.


Ironically enough, earlier today I was pondering that "now they have two problems" quote about regexes, applying it to singletons instead. :)

Quote:

- to allow runtime polymorphism in order to select some singleton subclass to treat as "the instance" (I am told this gets used for abstracting away rendering layers when you - somehow! - don't know until runtime which graphics API you're going to use.)


Bingo! Regard cin & cout as legacy examples[/quote]

... Why wouldn't the program know at compile time what cin and cout are? Won't they always have the same implementation for the platform being compiled on?

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by Jingo
Singletons are not replacements for globals. The only thing they have in common is the global point of access. The singleton pattern ensures that there is only one instance of a class, a global does not do this.


I could be completely misunderstanding, but when I fill in the missing words and substitute the backreferences in "a global does not do this", I get "using a global variable does not ensure that there is only one instance of the global variable."



No, you get "using a global variable does not ensure that there is only one instance of a class".

Share this post


Link to post
Share on other sites
A singleton will prevent the global being changed in the middle of your code to point to something else.

RenderManager *renderManager;

void DoSomethingInMiddleOfGameLoop()
{
//...
renderManager = new RenderManager;
//...
}

Of course you would be an idiot if you actually did this, and if your were working with someone that did then they shouldn't be there for much longer.

Share this post


Link to post
Share on other sites
I know two cases where a singleton may be useful:

1) The class is part of a class hierarchy and needs to override some virtual functions. For example, it can be useful to have a "dummy" or "empty" object that does nothing. It would be a waste to create several such objects. In this case, you get the object with the Instance() function but you still pass the pointer in a bigger system that is unaware of the existance of the singleton.

2) You have only one instance right now, but you plan to have several later. In this case, the change will be smaller if the object is defined as a class in the first place.

Otherwise, a namespace with functions that "privately" access data defined in the source file (.cpp) is a much better approach I think. It separate interface and implementation even more than a class without the cost of using virtual functions (which are the way to separate those with classes)

alexk7

[Edited by - alexk7 on July 7, 2004 7:29:46 PM]

Share this post


Link to post
Share on other sites
If you have multithreading, isn't using a singleton an option to make sure the object isn't changed or reinstantiated by a second thread while the first is using or changing the object?

Or suppose I have a class with a list of objects; say molecules. Each instance of a molecule will have certain physical properties that do not change. There is absolutely no reason for me to have more than one instance of each molecule, and once a molecule is created I don't want it changed. I don't want to duplicate this list, as it could be huge. If I have different versions floating around a large application, that could be problematic. If I have a singleton I can be sure that there will be only one instance of my list of molecules, and I don't need to worry that sixteen threads might be simultaneously adding the same molecule to the list (maybe even with disagreements about their properties?).

Let me sum up. I want a Flyweight, and I don't want to use a factory class to do it.


Share this post


Link to post
Share on other sites
Create it statically, let the class be the 'factory' for its own objects (actually just a registry).

IIRC the Python environment does this internally for the integer type (since int objects are immutable), caching instances of small numbers (straining my IIRC further, up to 100).

Jingo: I think we are talking at cross purposes. If you have the global variable, you don't need the object any more. So my reasoning goes, the variable becomes the thing you are using, there is only the one variable, so of course you only have one instance. That is, a global is intrinsically 'static', and therefore singleton.

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