Interface für Singleton



  • Vergiss einfach, dass es das Anti-Pattern Singleton gibt.



  • Danke für eure Antworten!

    Was spricht denn gegen ein Singleton? Mein Objekt soll nur einmal existieren, was doch für ein Singleton spricht?

    Was ich erreichen möchte:
    Ein Interface, welches dem Programmierer Zugriff auf ein Objekt gibt, welches nicht von ihm instanziert werden muss. Die Implementierung soll in einer aneren Klasse erfolgen, welche dem Programmierer aber nicht bekannt ist. Idealerweise sollte das Objekt nur einmal existieren, da nur eine Instanz davon nötig ist.

    Wie würde ich das denn ohne Singleton hinbekommen?



  • Nimm ne globale Variable.



  • Das ist aber aus Sicht der OOP auch nicht wirklich besser.. Gibt es da keine schönere Lösung?



  • Nicht wirklich. Was du beschreibst das du brauchst ist eine globale Variable. Die kann man in eine Klasse tun und Singleton nennen, aber sie wird dadurch nicht besser.
    Die einzige Möglichkeit das weg zu kriegen ist soweit ich weiß das Design zu ändern. Eine globale Variable sollte nicht nötig sein. Vielleicht gehört sie logisch zu einer Klasse, dann kannst du sie dort als static Variable anlegen. Vielleicht brauchst du sie auch gar nicht oder kannst sie irgendwo als Parameter mitgeben.
    Wenn man keine Objekte modelliert kommt man halt mit OOP nicht weit.



  • Was willst du denn abstrahieren? Den Singleton-Mechanismus an sich, oder nur die eigentliche Funktionalität der Singleton-Klasse? Ersteres ist schwachsinnig, weil man beim Aufruf einer statischen Methode per Definition wissen muss, zu welcher konkreten Klasse sie gehört. Letzteres ist ganz normale Ableitung.



  • @Schoasch
    Und nu verrate uns noch warum du meinst dass es nur ein Objekt von der Klasse geben soll.



  • Wie würde ich das denn ohne Singleton hinbekommen?

    static Singleton& get(){
      static Singleton instance;
      return instance;
    }
    

    Ansonsten:

    ich definiere für meine Klassen immer ein Interface mit pure virtual functions und implementiere diese in einer anderen Klasse.

    Warum? Meist unnoetig, da es sowieso nur eine Ableitung gibt. Meine Erfahrung. Deine Vorgehensweise wuerde ich als Java-like betiteln.



  • hustbaer schrieb:

    @Schoasch
    Und nu verrate uns noch warum du meinst dass es nur ein Objekt von der Klasse geben soll.

    Oder besser: Warum meinst du, können/dürfen nicht mehrere Objekte der Klasse existieren?



  • knivil schrieb:

    Ansonsten:

    ich definiere für meine Klassen immer ein Interface mit pure virtual functions und implementiere diese in einer anderen Klasse.

    Warum? Meist unnoetig, da es sowieso nur eine Ableitung gibt. Meine Erfahrung. Deine Vorgehensweise wuerde ich als Java-like betiteln.

    Auch bei nur einer Ableitung bietet dieses Interface basierte Design die Vorteile des PIMPL-Idioms.
    Wird Beispielsweise eine Klasse in sehr vielen anderen ÜEs des Projektes genutzt,
    so müssen all diese ÜEs neu kompiliert werden, wenn sich z.B. an den Attributen der Klasse etwas ändert.

    Nutzt man aber Interfaces, die sich nur sehr selten ändern, so braucht man im Normalfall nur die ÜE der einen Klasse neukompilieren, was bei großen Projekten durchaus Zeit sparen kann.

    Außerdem verbessert es die Austauschbarkeit der Implementation, auch wenn das vllt nicht genutzt wird...

    Dem entgegen steht Langsamkeit in der Ausführung durch zusätzliche Indirektion (ist aber meist zu vernachlässigen).

    Und zum Singleton:
    Interfaces kann man sowieso nicht instanzieren, da sie rein virtuelle Methoden besitzen.
    Du brauchst also irgendeine Methode, von der du das eigentliche Objekt beziehst.
    Diese Funktion könnte so aussehen:

    RootWidget * get_root_widget()
    {
        // Win32RootWidget ist hier mal die Implementation des RootWidget-Interfaces
        static Win32RootWidget instance;
        return &instance;
    }
    

    Da man von außen ein RootWidget nur über diese eine Funktion abgreifen kann, ist es in gewisser Weise ausgeschlossen, dass noch weitere Instanzen erzeugt werden.



  • DrakoXP schrieb:

    Auch bei nur einer Ableitung bietet dieses Interface basierte Design die Vorteile des PIMPL-Idioms.

    Es bringt ein paar Bruchteile der Vorteile des PIMPL-Idioms, aber dafür tausend Nachteile.

    Der grösste Nachteil ist wohl dem Benutzer dynamisches Memorymanagement aufzuzwingen. Das ist nie gut und wird in guten Programmen von einer Wrapperklasse erledigt, was hier aber wieder PIMPL wäre.

    Dann ist es auch noch unnötig langsam und hat die traditionellen Nachteile der Vererbung, vor allem den Verlust der Kapselung.



  • @DrakoXP: PIMPL ist unabhaengig von IInterfaceSomething. Ich brauche kein ISomething in kombination mit PIMPL. Sehe auf Anhieb wo Interfaces/Vererbung hier noetig ist: http://herbsutter.com/gotw/_100/

    Außerdem verbessert es die Austauschbarkeit der Implementation, auch wenn das vllt nicht genutzt wird...

    Meine Erfahrung: Dem ist nicht so.



  • knivil schrieb:

    Außerdem verbessert es die Austauschbarkeit der Implementation, auch wenn das vllt nicht genutzt wird...

    Meine Erfahrung: Dem ist nicht so.

    Nach meiner Erfahrung ist das schon so. Allerdings nur wenn man die Einschränkung hat abhängige Programmteile nicht neu übersetzen zu können.
    Wenn man immer Rebuild-All machen kann, dann ist es natürlich wurst.

    Weiss nicht auf welchen der beiden Fälle du dein "ist nicht so" bezogen hast.



  • knivil schrieb:

    @DrakoXP: PIMPL ist unabhaengig von IInterfaceSomething.

    Ich habe nie gegenteiliges behauptet. Ich schrieb lediglich, dass man mit so einem Interface einige der Vorteile von PIMPL genießt.

    Dass dieses Design auch einige/viele Nachteile hat/haben kann, ist mir auch durchaus bewusst. Ich wollte mit meiner Argumentation nur deutlich machen,
    dass es auch Kontexte geben kann, in denen es mehr oder weniger sinnvoll ist,
    auf Interfaces zurückzugreifen.

    DirectX und Ogre basieren auch nicht grundlos auf Interfaces (zugegeben, das sind Bibliotheken und Interfaces haben eine wesentlich stabilere ABI als normale C++-Klassen, die schon beim gleichen Compiler zwischen Release und Debug Build Probleme machen können...)



  • Danke für eure Antworten!

    Ich habe mich dazu entschlossen, statt dem Singleton die Klasse ganz einfach instanzieren zu lassen. Es ist wahrscheinlich richtig, dass ich das Klassendesign noch mal überdenken sollte wenn ich lauter globale Objektinstanzen (Singletons) brauche..


Anmelden zum Antworten