Wann ist es in Ordnung, eine globale Variable zu verwenden?

22

Ok, das ist also wirklich eine Art Teufelsanwaltfrage.

Wann sind globale Variablen in Ordnung, und wenn nie, welche würden Sie als Alternative verwenden?

Ein interessanter Nebenfall zu dieser Frage: Wie unterscheidet sich ein öffentliches statisches Klassenfeld von einem globalen?

ocodo
quelle
5
Code Complete , 2. Ausgabe, §13.3.
Jerry Coffin
1
Multithread-Anwendungen erfordern so ziemlich globale Variablen.
Aqua
Siehe Software-Kopplung
PP.
4
Bei @aqua Multithread-Anwendungen können globale Variablen am meisten Schaden anrichten. Jeder hasst komplexe Sperrlogik.
Luiscubal
1
@JerryCoffin Wenn das Veröffentlichen eines Links als Antwort ohne Zitieren der entsprechenden Passage eine schlechte Praxis ist, wird auch ein Abschnitt eines Buches ohne Zitieren der entsprechenden Passage zitiert. Besonders deshalb, weil Bücher nicht so frei und leicht erhältlich sind wie Webseiten.
Braden Best

Antworten:

18

Soweit ich weiß, ist ein öffentliches statisches Feld im Grunde genommen ein globales Feld, da es von überall aufgerufen werden kann, mit der Ausnahme, dass es den Namespace nicht verstopft.

Das einzige Mal, dass ich persönlich "globale" Variablen in meinem Code verwende, sind öffentliche statische Felder, die unveränderlich sind. In diesem Fall besteht kein Grund zur Sorge, dass der Wert durch andere Teile des Programms verfälscht wird, und es ist natürlich viel schöner, als ein Dutzend Variablen mit denselben permanenten Werten in jeder Klasse zu haben.


quelle
2
Ich würde ein unveränderliches Feld als Konstante bezeichnen .
aioobe
14

Persönlich verwende ich Globals für die Laufzeitkonfiguration. Wenn eine Konfigurationseigenschaft beim Start der Anwendung geladen wird und sich nur selten (und nur von einer Stelle aus) ändert, ist es schrecklich und fehleranfällig, sie an alle Methoden weiterzugeben, die möglicherweise verwendet werden müssen es irgendwann. Besser ist es, etwas zu verwenden, das von jedem Ort in den Geltungsbereich gebracht werden kann, an dem es benötigt wird, da dies Ihre Methodensignaturen und Aufrufsites nicht überfrachtet und verdeckt.

Anon.
quelle
Würden Sie hierfür ein reines Global oder ein öffentliches Static / Singleton verwenden?
ocodo
1
@ Slomojo: Auf keinen Fall ein Singleton. Je nach Situation entweder Statik in einer Konfigurationsklasse oder einfache Globale mit einem CONFIG_oder einem CFG_Präfix.
Anon.
+1 Die einzige Änderung, die ich vorschlagen würde, ist zu sagen "... fehleranfällig, um es an jede andere Methode in jeder anderen Klasse weiterzugeben". Andernfalls kann es sinnvoll sein, mit dem zu unterrichten, was auch immer dazu dient - Singleton, denke ich.
Michael Durrant
8

Mit Ausnahme von Echtzeit- / eingebetteten Systemen sollten Sie eigentlich nur globale Werte für konstante Werte verwenden. Wenn Sie das Gefühl haben, dass Sie Ihr Problem ohne sie nicht lösen können, tun Sie wahrscheinlich etwas falsch.

Sehen Sie sich auch das Singleton-Muster an . Es bietet eine bessere Lösung für globale Unternehmen in Situationen, in denen Sie einen globalen Zugriffspunkt benötigen.

Davor Ždralo
quelle
8
Ich würde wahrscheinlich empfehlen, Singletons zu meiden.
ocodo
Ich behaupte nicht, dass Singletons großartig sind, aber ich denke immer noch, dass sie globale Variablen um ein Vielfaches übertreffen.
Davor Ždralo
Konstante Werte müssen nur in dem Bereich / Modul zugänglich sein, in dem sie relevant sind. Eine Konstante TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOPist nur in der einen Datei / Klasse / Sektion relevant, in der 'diese spezielle Schleife' erscheint.
Cthulhu
1
Die Felder eines Singletons sind globale Variablen, daher sehe ich keinen Unterschied.
sleske
1
@Cthulhu lassen Sie mich selbst zitieren: "In solchen Situationen, wenn Sie etwas brauchen, um einen globalen Zugangspunkt zu haben".
Davor Ždralo
6

Das Problem mit globalen Variablen besteht darin, dass Sie sie überall in Ihrem Code kennen müssen. Wenn Sie jedoch einmal entschieden haben, dass Sie etwas über ein bestimmtes globales System wissen müssen, können Sie es nur wenig weiter nutzen. Meiner Meinung nach sollten Sie daher nur sehr wenige globale Variablen haben, aber bei den wenigen, die Sie haben, sollten Sie die maximale Laufleistung herausholen.

Ein weiteres Beispiel für etwas, das mir so einfällt, ist die Verwendung von Mixins in Ruby.

btilly
quelle
Welche beispielhaften Anwendungsfälle würden Sie für diese Verwendung von Globalen vorschlagen?
ocodo
1
@Slomojo: Ein Beispiel für Globals, die mir nichts ausmachen, ist die Verwendung von @ARGV und $ _ in Perl. Ein Beispiel, das mir wichtig ist, ist die Verwendung von Globalen für die billige Übergabe von Parametern an Unterprogramme.
btilly
5

Es dreht sich alles um Namespaces.

Stellen Sie sich für einen Moment vor, dass jeder auf der Welt den gleichen Nachnamen hatte. Was für ein Chaos.

(In Indien haben die Sikhs alle den gleichen Nachnamen: Singh - Schau mal)

Christopher Mahan
quelle
6
Es verwendet alle über Namespaces zu sein, aber jetzt ist es an der Thread - Sicherheit.
dan04
6
@ dan04 Es geht darum, kein abscheuliches Design mit gruseliger Action auf Distanz zu haben.
Tom Hawtin - Tackline
2
@Tom: Vielleicht können wir das "Quantenprogrammierung" nennen
Christopher Mahan
4

Kurzfassung: Wenn es einfacher ist, über das Programm nachzudenken. In der Regel handelt es sich um eine weit verbreitete Art von globalem Status oder statischer Ressource.

Lange Version: Tom Hawtin sagte "mit gruseliger Aktion auf Distanz" ... das ist genau das Problem bei Globals - man muss wissen, wo und wie es verwendet wird, oder man kann einige wirklich seltsame und schwer aufzuspüren bekommen Bugs. Einheimische sind nichts anderes als eine Strategie, um den Umfang dessen zu reduzieren, was der Programmierer verstehen muss, um über das Programm nachzudenken.

Eine andere Seite des Problems mit dem Wissen, wo sie verwendet werden, ist, dass es zu doppelten Globalen kommen kann. In diesem Fall können die Dinge sehr seltsam werden, da die meisten Programme var1 abrufen und setzen, während var2 an einigen Stellen verwendet wird, um zu halten die gleichen Informationen. Insbesondere, wenn mehrere Personen an demselben Code arbeiten. IDEs können hilfreich sein, wenn es darum geht, die Verwendung zu finden, wodurch die Kosten für globale Anwendungen gesenkt werden. Für Duplikate tun sie jedoch nichts.

Je mehr Globals Sie haben, desto schwieriger ist es, den Überblick darüber zu behalten, was mit ihnen geschieht. Sie sollten wenige und weit voneinander entfernt sein.

jmoreno
quelle
Letztendlich ist es eine ziemlich schlechte Idee, veränderbare Globals zu haben. Die einzige Ausnahme ist das Arbeiten mit extrem beengten Hardwareverhältnissen, z. B. bei eingebetteter Programmierung. Zumindest sollten Kandidaten für Globals in der regulären Programmierung in statische Member von Klassen oder Modulen aufgeteilt werden. Alles, was sich ändern lässt, sollte auch als Sonderfall betrachtet werden, wenn Sie in einer Umgebung mit mehreren Threads arbeiten. Verwenden von Sperren / Futures / Versprechungen oder einer anderen Methode zur Thread- / Transaktionssicherheit. - Da es sonst niemand erwähnte, sah man das Problem der Essensphilosophen.
Ocodo
1
Zweifellos können Threads die Arbeit mit veränderlichen Globals erschweren, aber aufgrund von Ereignissen kann das gleiche Grundproblem auftreten. Ich stimme dem Vorschlag zu, mich als statische Mitglieder einzubringen, und würde noch weiter gehen und sagen, dass sie idealerweise private statische Mitglieder sein sollten.
Jmoreno
3

Die beiden Fallstricke mit Globals und Singletons sind Testbarkeit und Bereitstellbarkeit.

Zum Testen habe ich zu viele überkomplexe Testgurte gesehen, um nur schlecht geplante globale und einzelne Lebensdauern zu bewältigen. Stellen Sie sicher, dass für solche Objekte klare und einfache Regeln für das Starten und Herunterfahren gelten.

In Bezug auf die Bereitstellbarkeit sind zwei Fälle zu berücksichtigen. Erstens, wie wird Ihr globales Objekt leben? Befindet es sich in einer statischen oder dynamischen Bibliothek? Wenn dieses globale Objekt für ein Plugin wiederverwendet wird, erhalten Sie zusätzliche Kopien? Was passiert zweitens, wenn dieses globale Objekt in einer parallelen Anwendung abgelegt wird? Ist es threadsicher?

Insgesamt denke ich, dass diese Gründe bedeuten, dass Globale und Singletons nur in Ausnahmefällen verwendet werden.

Schmiede
quelle
2

Bei der Entwicklung kritischer eingebetteter Systeme werden normalerweise globale Variablen verwendet.

Stapelgrößen sind winzig, alles ist statisch zugeordnet ( malloc()ist verboten), globale Variablen sind außerhalb der Bibliothek, zu der sie gehören, verborgen.

mouviciel
quelle
0

In einer schrecklichen VB6-Codebasis, die globale Systeme missbraucht, als gäbe es kein Morgen, bin ich schuldig, eine neue einzuführen:

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

Ich denke, es ist einer der wenigen gültigen Anwendungsfälle für ein globales Objekt.

Mathieu Guindon
quelle