3

Imagine you have a large application project, the code is split into a range of subsystems implemented as classes derived from CBaseSubsystem.

Here already comes my first question:

  • Is it a good idea to organize subsystems as classes [derived from a base class]?

Then, you have your subsystem classes. Now, you will need create have instances of them somewhere. But where?

  • Is it a good idea to have every subsystem instance stored in a global variable, for example:
    extern CEventSystem* g_EventSystem;

  • Where should the instances be actually created? All together in a main()-like function?

  • Or is it better to avoid global variables entirely and organize the instances in a CSubsystemManager class or the like?

  • Would using singleton classes be an appropriate approach?

Jarx
  • 31
  • 1

4 Answers4

1

Very similar to this. I'd avoid Singleton, because it is absolutely unnecessary here and brings about many other issues.

Create the instances in a main-like routine. If something needs a system, provide access to it through some means, be it a parameter passed directly to that something or a container that provides access to these systems (IE: CSubSystemManager). You likely don't need to go so far as to write CSubSystemManager.

Avoid global state, there's a reason it has a stigma.

Community
  • 1
  • 1
Sion Sheevok
  • 4,057
  • 2
  • 21
  • 37
  • +1 for highlighting the perils of global state and discouraging the Singleton anti-pattern. – mavam Aug 08 '11 at 10:23
0

If you need a way to access an instance of each subsystem, I would avoid using "extern" and instead go with a singleton that gives you access to an instance of CSubsystemManager. The manager itself can take care of instantiating and managing your subsystem objects.

Stephan
  • 1,007
  • 7
  • 9
  • But every time one subsystem wants to communicate with another, it will need to "find" the other one via the subsystem manager - won't what be a problem? – Jarx Mar 01 '11 at 20:56
  • It depends on how expensive the lookup function is. You could store the subsystem instances in a vector that's indexed by a int (you could define an enum value for each subsystem type). alternatively, you could you could do the lookup for the relevant subsystems on object construction and store a reference in a class variable. That way, you'd only do the lookup once. – Stephan Mar 01 '11 at 21:51
  • The latter one sounds like a reasonable solution, yes, thank you – Jarx Mar 01 '11 at 22:09
  • What you're refering to is classic "find-and-bind". you need a Registry (impl wise a simple hashtable will do) :) – mohaps Mar 06 '11 at 02:24
0

If you want to talk theory rather than provide a concrete question then consider designing in terms of a combination of Factory and Singleton with the possibility of Strategy in subsystems which may implement a similar operation for a range of different object types.

The main subsystem Factory is itself a singleton whose purpose is I hope obvious. Use lazy evaluation to allow only required subsystem objects to be loaded as needed. You may want to consider providing each subsystem with a reference counting mechanism which will allow them to be dropped when no longer needed. Some subsystems may themselves be singletons and/or may also implement Strategy pattern to provide a particular service for a range of class types. This service may be for example validation, rendering, serialisation etc.

The value judgement of whether it is a "good idea" to build your application in this way is not for me to say. I would rather let older wisdom speak to that.

dex black
  • 637
  • 6
  • 8
0

My solution would create a combo of a singleton Registry, AbstractFactory and Factory.

//in base module

class ISubsystem{} //an interface for a subsystem

//in module code
Registry::instance()->registerFactory("subsystem1",new Subsystem1Factory());

//in user code
IFactory* factory = Registry::instance()->getFactory("subsystem1");
ISubsystem* subsystem = factory->createObject(...); //you can implement whatever policy in factory impl. (like singleton etc.)
mohaps
  • 1,010
  • 5
  • 10