Singleton versus Monostate Pattern

Started by
123 comments, last by zealouselixir 20 years, 4 months ago
The

"You can also get into trouble if people, usually unknowingly, try to access the renderer before it's ready or after it's been shutdown."

made me think you were not talking about singletons, which guarantee they are initialized when you use them, and shut down automatically ... ah, well ... sorry

quote:This can cause troubles, or at least some hassle, when you try to re-use your object class elsewhere. For instance, if you decide to make a stand-alone server to host your game on-line, then the object will still depend on a Renderer, even though you may not need to render anything in the server app. Or, maybe you decide to ditch your internal renderer and use some middleware graphics API. Oops! I bet they didn't derive their renderer from your Renderer base class. Now you need to re-work everything.

You have a perfectly valid point here. If that's how you plan to design your game, then the approach of passing a renderer interface as parameter might not be the best one. (Even though you would just need to include the interface definition for the renderer. You would never need to instantiate any renderers because you wouldn't be calling the render() method (which requires it) anyway.)

You can make your object not rendereable by it self. But then the object still has to provide some information that enables the system that will actually draw it to do it's job. You are again making dependencies. You just need to take care that the drawing system depends on an interface (that provides needed info), not on a (concrete) object class.

An object could also implement more than one interface to better divide the services it provides. It could implement an interface relevant to the rendering system and an interface relevant to the server-side system.

You will always depend on something - you just can't eliminate that. But when you DO depend, depend on an abstract interface instead on a concrete class.

quote:Or, maybe you decide to ditch your internal renderer and use some middleware graphics API. Oops! I bet they didn't derive their renderer from your Renderer base class.

That's not keeping you from making an adapter that implements the Renderer interface by using some X API (that's somehow what all engines more or less do). And I bet the "middleware graphics API" doesn't know anything about your Object class either.

quote:So again, the point I was trying to get at is that the Object shouldn't ever depend on any Renderer.

But then as I already said it ... the Renderer would have to depend on the Object. Which is cool - if you find it better that way. I'm just trying to show you, that you're not ending up with less dependencies. You just need to make them weak instead of strong (which relates to the singleton when you always end up making strong dependencies).

// edit:
The example I gave was from a 2d game that did just some trivial rendering. It's just an example, how you can avoid *singletons*. Sorry, again, for the misinterpretation.

p.s.: not arguing with you, just discussing the stuff ...

[edited by - jure on December 6, 2003 9:37:51 PM]
Advertisement
quote:Original post by jure
My point with "global functions" is not to encourage their use! I encourage the OO approach. I just want to show that using singletons is somewhat identical to the usage of global functions. So if you are using singletons you could as well use global functions - you would get the same flexibility problems.

The singleton violates a lot of important principles of OO that try to increase the flexibility of the software by reducing various types of dependencies between classes.

So if you want me to choose between singletons or global functions ... you''re kinda offering me the same thing with minor differences. I don''t know ... maybe I would choose global functions because they''re simpler and clearer. But whatever you choose, you won''t gain any advantage over a real OO approach.


I was never arguing about singletons VS "OOP", sorry if it sounded like i was.

However i dont agree that *EVERYTHING* should be OOP, there are still going to be some things that dont fit well with an object orientated approach.
Memory Manager would be one for example, in fact any form of manager eg Inputs, Resources etc.
IMO, if you try to make *everything* OOP, then you end up fighting it in places because your too rigid. The idea is to use whatever style solves the particular problem easiest. We all use globals (new/delete for example, most API functions etc) and singletons offer a reasonable alternative to those.

They certainly arent OOP though, for exactly the reasons already listed, but at least IMO, they are preferred to global "module" based code.

Of course if you can do it the "traditional" oop way, do that, just about everything the application will be instantiating will be "traditional" classes, singletons are purely for where the only "solution" to the problem would be a global module, in which case a singleton can probably be used instead.

One thing i will say is that thanks to this thread, i think i now dislike using the Get() all the time, i think in the future i will probably just have the init, and store off the pointer, then the pointer can be passed to whatever uses it and the coupling is explicit. eg turns singletons into a "module in a class" rather than the "global accessor"





Not to beat a dead horse... but

First off API''s and managers can also be implimented in a facade or other OO pattern, there is no need to flatten it in the way that you are describing.

I think the point this whole thread is trying to get across is that singletons AND monostates are, for the most part, unecessary and possibly dangerous if you take a close look at the whole system.

Take for instance...

What if you need JUST ONE of a class. Why not just have any more object creations throw an exception based on a static variable or other resource indicator. That way you can change behavoir of object creation at any time by only modifing one file. This object could be held by the application in whatever manner they felt necessary. This way you enforce a number of objects without forcing global functions on the program.

One problem that I have though of and is a problem for me. I planned on dropping in a scripting language into my game, but with singletons or monostates running arround it''s more difficult. Anyone who has access to the program can get access to these objects and possibly do weird things to the program. These globally accessed items can be quite a liabilty in this way. ANY STATIC / GLOBAL FUNCTION can also be a liability in this model.

Singletons and monostates, although simple and effective in some situations, can complicate the project down the line.

out of time... I''ll be back later.
quote:Original post by snowmoon Why not just have any more object creations throw an exception based on a static variable or other resource indicator. That way you can change behaviour of object creation at any time by only modifing one file. This object could be held by the application in whatever manner they felt necessary. This way you enforce a number of objects without forcing global functions on the program.

The program would then have to be able to query whether there was an object available to be created, or what the maximum number was etc. That would get to be very messy, repetetive and bug-likely client code.

quote:One problem that I have though of and is a problem for me. I planned on dropping in a scripting language into my game, but with singletons or monostates running arround it's more difficult.

why is that?
quote:Anyone who has access to the program can get access to these objects and possibly do weird things to the program.

er... only if you let them.

quote:These globally accessed items can be quite a liabilty in this way. ANY STATIC / GLOBAL FUNCTION can also be a liability in this model.

take a deep breath... no they aren't.

not that I think Singletons are a good idea, as I've already contributed to this thread, but your comments are incorrect.

[edited by - petewood on December 8, 2003 9:26:07 AM]
If an object is tied directly to one resource in the system, singletons are out because they are a hack, monostate seems sloppy too, so why not just throw an error when trying to create the object and no resources are availible?

Scripting... um... don''t jump down my neck... I was saying in my context.

Because of java reflection, any object can query and execute any other publicly avbailible method/variable in the system. Because of this if I allow general scripting people *COULD* access singletons or any other global function in the program. Ergo any global method COULD be called from a script as long as they have access to the reflection code. Would it not be better to prevent this through *GASP* proper abstraction?



This topic is closed to new replies.

Advertisement