   Singleton vs Class vs Namespace
  When designing a subsystem for which there needs to be in any case at maximum one instance at any time (like resource manager, 3D engine, whatever) there's various ways it can be done:- setting it up as a Singleton Class object and offering the functionality through (non-static) methods of that class- exposing subsystem functionality via static class methods of a (non-Singleton) class- exposing subsystem functionality via static (non-class) functions belonging to a namespace (to avoid polluting the global namespace)Anything that would recommend one design choice over the others, except for the obvious advantage of the Singleton approach of offering more flexibility and control should a second instance of a subsystem ever turn out to be necessary?Alex   
  I use more than one (identical and different) resource manager => no "one only".i use more than one 3d engine instance in some of the tools => no "one only".whatever, never do it one-only.if it is stateless stuff (like helper functions), collect them in a namespace. if it is something belonging to a class, but not an instance, create a static class method.   ;Quote:Original post by ak-73When designing a subsystem for which there needs to be in any case at maximum one instance at any time (like resource manager, 3D engine, whatever) there's various ways it can be done:Regular instances, created by user as needed. If you only need one, only create one. Example:struct OnlyEverNeedOne {};struct Engine {  void foo() {    while (running)   instance.doSomething();  }  OnlyEverNeedOne instance;};Isn't this easy? There can never be more than one, it's not static, or anything else, and can be trivially refactored if you ever need more.Quote:Anything that would recommend one design choice over the others, except for the obvious advantage of the Singleton approach of offering more flexibility and control should a second instance of a subsystem ever turn out to be necessary?One thing globals (plain or Singletons) do *not* offer is any kind of flexibility. They are the exact opposite, making design completely rigid.Namespaces are good, as mentioned, for stateless free functions.   ;Quote:Original post by davepermenI use more than one (identical and different) resource manager => no "one only".i use more than one 3d engine instance in some of the tools => no "one only".whatever, never do it one-only.That is again a question of design though, no? For example it should in theory always be possible to offer a unified interface with which the game engine can put out state in 3D.The game engine might have access to a function/method like "renderMesh()" and that could be the method of a Singleton, a static class function or a static non-class function in theory.So I am not sure I can follow your logic here - can you elaborate? Thanks.Quote:if it is stateless stuff (like helper functions), collect them in a namespace. if it is something belonging to a class, but not an instance, create a static class method.Well, that is pretty much the *definition* of it though. ;-)Alex   ;Quote:Original post by ak-73The game engine might have access to a function/method like "renderMesh()" and that could be the method of a Singleton, a static class function or a static non-class function in theory.A singleton (as mentioned) will limit your design, not make it versatile.  To understand why, type "singleton" in the search bar on this site and click on practically any of the zillion previous threads that come up.  The easiest point is you never know if you'll need more than 1 (as mentioned) and its unflexibility makes it hard to refactor later.  Also it encourages global state (that's what it is after all - a global that's slightly harder to refactor than a global).As for namespace vs static class method, chances are you'll just want to use a namespace.  This tends to aid encapsulation, and keep you in the mindframe of generalizing your functions for greater reuse.   ;Quote:Original post by AntheusQuote:Original post by ak-73When designing a subsystem for which there needs to be in any case at maximum one instance at any time (like resource manager, 3D engine, whatever) there's various ways it can be done:Regular instances, created by user as needed. If you only need one, only create one. Example:struct OnlyEverNeedOne {};struct Engine {  void foo() {    while (running)   instance.doSomething();  }  OnlyEverNeedOne instance;};Isn't this easy? There can never be more than one, it's not static, or anything else, and can be trivially refactored if you ever need more.Okay, I get that. But - my question would specifically be if there would be an advantage of this over the other two. I have brought the term Singleton in only because a) there should in theory by design never be one more than one instance necessary for a subsystem of a kind.b) as such a Singleton class is more comparable to the static method/static function approach.I don't want to get hung up on *Singleton*, I'd like to hear if there is some advantage or disadvantage to any of the three approaches that my eye does not detect. :-)Quote:Quote:Anything that would recommend one design choice over the others, except for the obvious advantage of the Singleton approach of offering more flexibility and control should a second instance of a subsystem ever turn out to be necessary?One thing globals (plain or Singletons) do *not* offer is any kind of flexibility. They are the exact opposite, making design completely rigid.Namespaces are good, as mentioned, for stateless free functions.But in theory they could manage state internally by relying on classes that are not exposed to the subsystem client. A 3D System might have a plethora of classes internally but they'll never show up in any header used by an external client, no?Given your suggestion that namespaces are good for *stateless* functions, why wouldn't this design be a good idea?Alex   ;Quote:Original post by popsoftheyearA singleton (as mentioned) will limit your design, not make it versatile.Well, that's the intention: to prevent the client from accidentally creating a second instance. However - is it more limited than creating a subsystem interface that is based on static methods and functions only? I doubt so.Quote:  To understand why, type "singleton" in the search bar on this site and click on practically any of the zillion previous threads that come up.  The easiest point is you never know if you'll need more than 1 (as mentioned) and its unflexibility makes it hard to refactor later.  Also it encourages global state (that's what it is after all - a global that's slightly harder to refactor than a global).It's more unflexible than a non-Singleton class object, I get that. But it's still more flexible than the two static approaches because it is based on class *objects*, no? Should ever the need for a second subsystem instance arise for some unexpected reason, I'd rather modify a Singleton class to handle two objects than refactor one of the static approaches to handle two objects.Quote:As for namespace vs static class method, chances are you'll just want to use a namespace.  This tends to aid encapsulation, and keep you in the mindframe of generalizing your functions for greater reuse.That's exactly what I was aiming for with my questions. Can you explain/state reasons?Alex   ;Quote:a) there should in theory by design never be one more than one instance necessary for a subsystem of a kind.And this is the problem - what happens if 6 months down the line you find out that you were wrong, and do infact need more than one? You will find yourself undertaking some very unpleasant refactoring. Quote:b) as such a Singleton class is more comparable to the static method/static function approach.Not really. static methods don't contain state (unless you are using a load of global vars as well - which is just as bad). Singletons typically contain some amount of state, which is a problem when (not if) you need to refactor away the singleton. Quote:But in theory they could manage state internally by relying on classes that are not exposed to the subsystem client. A 3D System might have a plethora of classes internally but they'll never show up in any header used by an external client, no?Given your suggestion that namespaces are good for *stateless* functions, why wouldn't this design be a good idea?But those internal classes which are not exposed to the client are internal state. Since state is the problem, no amount of hiding the internal state is going to help you much - You still have a nightmare infront of you refactoring away that state. Antheus and daveperman are bang on the money here, and Antheus's solution is always the best way to code a singleton (i.e. don't!)There are some pretty obvious reasons why believing that you'll only ever need a single 3D subsystem is limiting in the future. What happens if you need to create multiple 3D sub-systems for multiple monitors? What happens if you want to have a choice of D3D/OpenGL support? Wouldn't it be nice to be able to instance 2 3D subsystems in 2 seperate windows to be able to compare D3D/GL for debugging reasons? The real thing to bear in mind, is that the second you use a global variable, a singleton, or monostate; you have fundamentally thrown away any chance of being able to re-use that code (or create multiple instances). static functions are absolutely fine when they only use the args and return vars:Vec3 add(const Vec3& a,const Vec3& b){  return Vec3(a.x+b.x,a.y+b.y,a.z+b.z);}but if you ever access a global var, you have got a state problem:static int gCount=0;static void blah(){  ++gCount;};Quote:Original post by ak-73Quote:  To understand why, type "singleton" in the search bar on this site and click on practically any of the zillion previous threads that come up.  The easiest point is you never know if you'll need more than 1 (as mentioned) and its unflexibility makes it hard to refactor later.  Also it encourages global state (that's what it is after all - a global that's slightly harder to refactor than a global).It's more unflexible than a non-Singleton class object, I get that. But it's still more flexible than the two static approaches because it is based on class *objects*, no? Should ever the need for a second subsystem instance arise for some unexpected reason, I'd rather modify a Singleton class to handle two objects than refactor one of the static approaches to handle two objects.Nah, the workflow is pretty much the same -- in particular because MySingleton::getInstance().doSomething() is more common than MySingleton &instance = MySingleton::getInstance; /*later*/ instance.doSomething(). Either way you're going to be mucking about directly with pretty much every function invocation.   ;Quote:Original post by RobTheBlokeAnd this is the problem - what happens if 6 months down the line you find out that you were wrong, and do infact need more than one? You will find yourself undertaking some very unpleasant refactoring.Either that *or* you *define* a subsystem so that there can never be more than one and everything that needs more than one instance is to be considered by design a part of the subsystem, a subsystem-subsystem if you will. In that case the interface would have to be accomodated to facilitate that.For example if I foolish built an Input subsystem that would support only a single input device, a joystick, and I found later that I was to add two-player functionality, then I might not redesign so that a second Input subsystem was enabled but that the current Input subsystem would offer functionality to handle mutliple input devices.Quote:Original post by SneftelQuote:It's more unflexible than a non-Singleton class object, I get that. But it's still more flexible than the two static approaches because it is based on class *objects*, no? Should ever the need for a second subsystem instance arise for some unexpected reason, I'd rather modify a Singleton class to handle two objects than refactor one of the static approaches to handle two objects.Nah, the workflow is pretty much the same -- in particular because MySingleton::getInstance().doSomething() is more common than MySingleton &instance = MySingleton::getInstance; /*later*/ instance.doSomething(). Either way you're going to be mucking about directly with pretty much every function invocation.How about the server side though? It seems pretty painful to me to have to rewrite the entire server code (contained within static methods/functions) so that a second internal subsystem was supported. Anyway I gather from the discussion so far that there are no significant differences between the 3 approaches other than what we have been debating here.Alex   