globale variable oder nicht?



  • dot schrieb:

    asc schrieb:

    Nenn mir bitte eine Gegenbegründung, warum man für Daten die genau einmal im System existieren kein Singleton verwenden sollte.

    Weil zumindest die Konstruktionsbeschränkung unnötig ist. Abgesehen davon, gelten natürlich sämtliche Nachteile von globalem Zustand allgemein, wie...

    Das gilt aber auch für die zwei direkten Alternativen: Als globale Varialbe oder als Funktion mit Rückgabe einer statischer Variable.

    Jedesmal wenn ich ein Recht in unserer Anwendung überprüfe (und das geschieht teilweise auf Datensatzebene - was gerade bei Listen zu sehr vielen Überprüfungen führen kann), kann ich nicht jedesmal die Daten neu einlesen (Dank verschiedenen Abhängigkeiten, Lizenzen etc. würde das jedesmal auch mehr als nur ein paar Abfragen bedeuten).

    Welche Alternativen siehst du, wenn man nicht ständig neue Objekte erzeugen will? Die Nachteile dank globaler Datenhaltung sind mir bekannt - aber für die Alternativen habe ich die gleichen Nachteile gefunden... Nun?



  • asc schrieb:

    Welche Alternativen siehst du, wenn man nicht ständig neue Objekte erzeugen will? Die Nachteile dank globaler Datenhaltung sind mir bekannt - aber für die Alternativen habe ich die gleichen Nachteile gefunden... Nun?

    globale Datenhaltung hat nichts mit Singleton zu tun.



  • asc schrieb:

    Jedesmal wenn ich ein Recht in unserer Anwendung überprüfe (und das geschieht teilweise auf Datensatzebene - was gerade bei Listen zu sehr vielen Überprüfungen führen kann), kann ich nicht jedesmal die Daten neu einlesen (Dank verschiedenen Abhängigkeiten, Lizenzen etc. würde das jedesmal auch mehr als nur ein paar Abfragen bedeuten).

    Welche Alternativen siehst du, wenn man nicht ständig neue Objekte erzeugen will? Die Nachteile dank globaler Datenhaltung sind mir bekannt - aber für die Alternativen habe ich die gleichen Nachteile gefunden... Nun?

    Ich fürchte, dass ich zu wenig Ahnung von der konkreten Anwendung hab, als dass ich da jetzt über Alternativen nachdenken könnte. Wieso genau müsstest du denn "ständig neue Objekte erzeugen"?



  • dot schrieb:

    Nexus schrieb:

    Andererseits sieht man oft den Fehler, dass jede Klasse, die nur einmal instanziiert wird, gleich zu einem Singleton gemacht wird.

    Genau das ist der Punkt. Eine globale Variable ist eine Instanz eines Typs. Ein Singleton ist ein Typ, der nur einmal instanziert werden kann.
    Auch wenn die übliche Implementierung eines Singleton in C++ einen globalen Zugriffspunkt auf diese eine Instanz impliziert, sind das imo immer noch zwei völlig unabhängige Konzepte, wie z.B. "Flugzeug" und "Urlaub" auch...

    Für mich macht die Unterscheidung überhaupt keinen Sinn.

    Einzig dass das Singleton 0 bis 1 Instanzen zulässt, die globale Variable aber immer genau 1x existiert ist ein Unterschied. Der aber meist nicht interessiert - globale Variablen verwendet man auch oft genug um etwas zu bauen was erstmal initialisiert werden muss. Vom Konzept her ist das dann genau das gleiche.

    Und vor allem: ich kann Code der mit lauter globalen Variablen arbeitet jederzeit in Code der ein Singleton verwendet überführen, und umgekehrt.

    "Singleton" ist also bloss ein Wort mit dem man versucht etwas schön zu reden, was nicht schön ist. Da "globale Variable" stärker negativ belegt ist als "Singleton", funktioniert das auch oft.



  • asc schrieb:

    Jedesmal wenn ich ein Recht in unserer Anwendung überprüfe (und das geschieht teilweise auf Datensatzebene - was gerade bei Listen zu sehr vielen Überprüfungen führen kann), kann ich nicht jedesmal die Daten neu einlesen (Dank verschiedenen Abhängigkeiten, Lizenzen etc. würde das jedesmal auch mehr als nur ein paar Abfragen bedeuten).

    Hat dein Programm kein "Session" oder "Connection" Objekt wo man solche Daten reinstopfen könnte?



  • hustbaer schrieb:

    Hat dein Programm kein "Session" oder "Connection" Objekt wo man solche Daten reinstopfen könnte?

    Nein... Auch wenn der Code dafür noch recht gut ist, handelt es sich hier um ein "historisch" gewachsenes Projekt (Einzelne Codeteile sind inzwischen über 10 Jahre alt). Teilweise mit direkter Bindung von Oberfläche an DB-Controls.

    Das einzige was über die gesamte Laufzeit existiert ist das VCL-Application-Objekt, und da kann ich nicht ohne weiteres igendetwas einfügen.



  • hustbaer schrieb:

    "Singleton" ist also bloss ein Wort mit dem man versucht etwas schön zu reden, was nicht schön ist. Da "globale Variable" stärker negativ belegt ist als "Singleton", funktioniert das auch oft.

    Wobei es ein Aspekt gibt die ich dennoch bei einem Singleton besser finde, als bei einer globalen Variable (gilt aber auch für Funktionen mit Referenzrückgabe einer statischer Variablen): Die Initialisierung erfolgt erst mit dem Zugriff - Probleme wegen geänderten Linkreihenfolgen sind daher geringer.

    Nein, ich will Singletons nicht schön reden. Ich ziehe sie aber (in seltenen Fällen) dennoch in Betracht. Dies sind im wesentlichen aber auch die von mir genannten Fälle (z.B. Für den Zugriff auf die Einstellungen zum Programm und für die Daten des aktuell angemeldeten Benutzers).



  • Naja gut wenn das ein GUI Teil ist, und es kein Objekt gibt wo man die Daten sinnvoll reinstopfen könnte, und man mit vertretbarem Aufwand auch keines einführen kann, dann mach nen Singleton.

    Eine schöne GetXYZ() Funktion die eine Referenz auf irgend eine Klasse zurückgibt. (Oder auch XYZ::GetInstance()).

    Der Sinn der GetXYZ() Funktion ist hier hauptsächlich dass man die Stellen schnell anfindet wo zugegriffen wird -- auf die Art lässt es sich leichter refactoren wenn das mal nötig sein sollte.

    Und der Sinn der Klasse ist hauptsächlich damit der Code übersichtlich bleibe. Ansammlungen von globalen Variablen und freien Zugriffsfunktionen entarten viel zu schnell - vor allem wenn mehr als ein Programmierer an einem Projekt arbeitet, oder der einzige Programmierer etwas zum Chaos neigt.

    Konzeptionell bleibt es für mich das selbe, aber es wäre wohl wirklich angebracht ein Singleton zu verwenden - aus oben genannten Gründen.



  • asc schrieb:

    hustbaer schrieb:

    "Singleton" ist also bloss ein Wort mit dem man versucht etwas schön zu reden, was nicht schön ist. Da "globale Variable" stärker negativ belegt ist als "Singleton", funktioniert das auch oft.

    Wobei es ein Aspekt gibt die ich dennoch bei einem Singleton besser finde, als bei einer globalen Variable (gilt aber auch für Funktionen mit Referenzrückgabe einer statischer Variablen): Die Initialisierung erfolgt erst mit dem Zugriff - Probleme wegen geänderten Linkreihenfolgen sind daher geringer.

    Kannst du auch mit globalen Variablen haben.
    Sagt ja keiner dass man die Zugriffe auf globale Variablen nicht hinter Getter-Funktionen verstecken kann. Und die verzögerte Initialisierung kann man dann in der Getter-Funktion machen.

    Genaugenommen kann man viele so kleine Änderungen machen, die alle nichts wesentliches ändern, bis am Ende dann was rauskommt was alle als Implementierung des Singleton Patterns bezeichnen würden. Daher meine ich ja auch dass es von Prinzip her das selbe ist.

    Nein, ich will Singletons nicht schön reden. Ich ziehe sie aber (in seltenen Fällen) dennoch in Betracht. Dies sind im wesentlichen aber auch die von mir genannten Fälle (z.B. Für den Zugriff auf die Einstellungen zum Programm und für die Daten des aktuell angemeldeten Benutzers).

    Jo, dagegen sag' ich ja gar nix.
    Ich verstehe schon dass manchmal Dinge Sinn machen die eigentlich nicht das sind was man sich wünschen würde.



  • hustbaer schrieb:

    Hat dein Programm kein "Session" oder "Connection" Objekt wo man solche Daten reinstopfen könnte?

    So ein Session Objekt ist letztendlich doch auch bloß wieder eine, mehr oder minder gekapselte, globale Variable oder?



  • Braunstein schrieb:

    So ein Session Objekt ist letztendlich doch auch bloß wieder eine, mehr oder minder gekapselte, globale Variable oder?

    Im wesentlichen schon 😉



  • Auf die Gefahr hin, hier aufgrund mangelnder RL-Erfahrung nicht mitreden zu können, aber Schema

    class app_t { // <- daraus mach von mir aus ein singleton ...
        private:
            int foo;
    
        public:
            int run() { /* backe, backe Kuchen ... */ return EXIT_SUCCESS; }
    };
    
    int main() {
    
        app_t app;
        return app.run();
    }
    

    braucht doch nie globale Variablen. Habe doch Eigenschaften von app_t bis dir schwindlig werde, aber globale!?



  • Braunstein schrieb:

    hustbaer schrieb:

    Hat dein Programm kein "Session" oder "Connection" Objekt wo man solche Daten reinstopfen könnte?

    So ein Session Objekt ist letztendlich doch auch bloß wieder eine, mehr oder minder gekapselte, globale Variable oder?

    Wenn ich Session-Objekt schreibe, dann meine ich schon was wovon es mehr als eins geben kann.
    Wenn ein Programm immer nur eins davon verwendet, OK, wird nur eins verwendet, aber der Code sollte auch funktionieren wenn es mehrere gibt.

    Bei der klassischen kleinen GUI Anwendung wird es oft egal sein. Bei Library-Code schon nichtmehr. Und bei Server-Anwendungen erst recht nicht.

    Beispiel: DevIL (aka. OpenIL).
    Da gibt's tonnenweise globale Daten. z.B. diverse Optionen die gerade aktiv sind, das aktuell ausgewählte Bild mit dem gearbeitet wird etcpp.
    DevIL in einem Programm mit multithreading verwenden = sich viel ärgern und viel beten und hoffen.
    Heisst du musst überall unnötige Locks einbauen, den kompletten State den du brauchst vor jeder Operation wieder neu einstellen (könnte ja ein anderer Thread verstellt haben). Und ... falls du mal eine Komponente integrieren musst die auch DevIL verwendet, aber nix von deiner "DevIL-Mutex" weiss, dann is feierabend.

    Diesen globalen State nun in eine DevIL-Session Klasse von der es nur eine geben kann zu packen macht natürlich keinen Sinn.

    Wenn es mehrere davon geben kann hat man aber gewonnen: jeder Thread bzw. jede Komponente legt sich dann einfach ihre eigene DevIL-Session an, und juchuii, nix kann mehr schief gehen. Und ganz ohne unnötige Locks.

    Wie gesagt, bei GUI Anwendungen ist es nicht unbedingt so wichtig, bzw. wird man kaum jemals echte Nachteile durch Singletons haben.
    Ich versuche die Dinger aber grundsätzlich zu vermeiden. Kommt vermutlich auch daher dass ich viel Library-Code schreibe bzw. geschrieben habe.



  • @Swordfish
    Jo. Jetzt haste globale Variablen in ein Singleton verwandelt.

    Was ist jetzt konzeptionell besser geworden dadurch?


Anmelden zum Antworten