Polymorphes Singleton



  • Abend,

    ich habe eine Singletonklasse:

    class ResourceManager {
    private:
       ResourceManager();
       ResourceManager(const ResourceManager& rhs);
       ~ResourceManager();
       ResourceManager& operator=(const ResourceManager& rhs);
    
    public:
    
       static ResourceManager& getInstance();
    
       virtual Buffer* createBuffer(Buffer::Type bufferType, IndexType::Type indexType) = 0;
    
    };
    

    Normalerweise würde ich die Zugriffsmethode so schreiben:

    ResourceManager& ResourceManager::getInstance() {
    	static ResourceManager instance;
    	return instance;
    }
    

    Jetzt gibt es da nur ein Problem: ResourceManager soll eine Basisklasse sein und Subklassen sollen die pure virtual methoden implementieren.

    Im Grunde soll es also so benutzbar sein:

    class FooResourceManager : public ResourceManager { ... };
    class BarResourceManager : public ResourceManager { ... };
    
    // Hier zur Laufzeit festlegen, dass der FooResourceManager benutzt werden soll
    Buffer* b = ResourceManager::getInstance().createBuffer(...); // Soll jetzt FooResourceManager::createBuffer() aufrufen
    

    Wie könnte man das in C++ implementieren?



  • Ach, schon wieder ein ResourceManager.



  • Moment, das macht für mich keinen Sinn. Gibt es beide Ressourcenmanager parallel oder möchtest Du, dass der jeweilige erzeugt wird, sobald er verwendet wird? Bist Du sicher, dass Du hier überhaupt ein Singleton benötigst? Wenn es schon zwei Typen von Ressourcenmanagern geben soll, dann nicht vielleicht auch mehrere Ressourcenmanager an sich?



  • Eisflamme schrieb:

    Moment, das macht für mich keinen Sinn. Gibt es beide Ressourcenmanager parallel oder möchtest Du, dass der jeweilige erzeugt wird, sobald er verwendet wird? Bist Du sicher, dass Du hier überhaupt ein Singleton benötigst? Wenn es schon zwei Typen von Ressourcenmanagern geben soll, dann nicht vielleicht auch mehrere Ressourcenmanager an sich?

    Es gibt zur Laufzeit genau einen. Also entweder wird der FooResourceManager benutzt, oder BarResourceManager etc.

    Ich brauche einfach nur an vielen Stellen Zugriff auf den ResourceManager.
    Ich will schreiben können:

    Bla* b = ResourceManager.getInstance().createXY();
    

    und es is mir an dieser Stelle egal, welcher ResourceManager das createXY() übernimmt.



  • Wenn du es zur Compilezeit entscheidest, dann

    ResourceManager& ResourceManager::getInstance() {
        static ResourceManager* instance = new FooResourceManager();
    //oder 
        static ResourceManager* instance = new BarResourceManager();
        ...
    }
    

    Oder ein initResourceManager( ResourceManager* ), wenns zur Leufzeit sein soll



  • Die Benutzung von Singletons ist doch ein Anti-Pattern. Warum willst du dir sowas antun?



  • Verwende DI - da hast Du das Problem nicht.

    Edit:
    http://www.youtube.com/watch?v=-FRm3VPhseI



  • theta schrieb:

    Verwende DI - da hast Du das Problem nicht.

    Welches Problem?



  • Es gibt zur Laufzeit genau einen. Also entweder wird der FooResourceManager benutzt, oder BarResourceManager etc.

    Das bedeutet, Du willst fixieren, welchen man benutzt. Dann geht techniks Ansatz.

    Aber

    Ich brauche einfach nur an vielen Stellen Zugriff auf den ResourceManager

    das habe ich befürchtet. Singletons nutzt man nicht, um an vielen Stellen Zugriff zu erreichen, sondern wenn man unbedingt will, dass es nur eine Instanz von dem Objekt geben darf. Diese Einschränkung ist hier aber vermutlich gar nicht notwendig.

    Insofern solltest Du das Singleton weglassen und die Instanz immer dem Objekt geben, das es benötigt. Dann sieht man die Abhängigkeiten auch beim Initialisieren und Du kannst es auch besser mit Unit-Tests testen etc.


Anmelden zum Antworten