# Wie kann man globale Variablen vermeiden?



## kossy (5. Aug 2011)

Hallo zusammen !

man sagt ja im Allgemeinen, dass globale Variablen in der Programmierung nicht gerne gesehen und recht unbeliebt sind. Unabhängig von der verwendeten Programmiersprache führt aber doch manchmal kein Weg adaran vorbei, solche Variablen zu benutzen oder? 

Wie und womit genau kann man denn die Verwendung solcher variablentypen gänzlich vermeiden und es besser lösen? Was genau ist besser, als die Verwendung globaler Variablen?

Viele Grüße
Kossy


----------



## Tomate_Salat (5. Aug 2011)

Seeehr Allgemein. Am geschicktesten wäre wohl hier mit DI zu arbeiten. Dazu kann man noch ein Config-Objekt anbieten, welches die Variablen verwaltet. Dieses sollte aber als "Singleton" gehändelt werden. Singelton ist auch wieder so ein Thema. Die eleganteste implementierung wäre mittels DI (womit wir wieder beim 2ten Satz wären). Also prinzpiell hilft einem in solch einem Fall z.B. Guice 

Konstante Werte kann man mit DI einfach injecten lassen:


```
@Inject
public Payment(@PayPalKey String key) {
```


----------



## maki (5. Aug 2011)

> Unabhängig von der verwendeten Programmiersprache führt aber doch manchmal kein Weg adaran vorbei, solche Variablen zu benutzen oder?


Doch, klar kann man sie vermeiden, vor allem in OO Sprachen.



> Wie und womit genau kann man denn die Verwendung solcher variablentypen gänzlich vermeiden und es besser lösen? Was genau ist besser, als die Verwendung globaler Variablen?


Alles ist besser als globale Variablen 
Man kann sich zB. Gedanken machen, wie diese "Variable" denn benötigt wird und sie dann einfach dort zugänglich machen ohne sie gleich global zu machen.
Dabei geht es um Design, man muss sich halt Gedanken dazu machen


----------



## turtle (5. Aug 2011)

> Unabhängig von der verwendeten Programmiersprache führt aber doch manchmal kein Weg adaran vorbei, solche Variablen zu benutzen oder?



Doch.

getter/setter-Methoden erlauben, das gezielte Verändern eines Attributes eines Objektes. Nehmen wie als Beispiel die Klasse Person mit dem Attribut "alter". Wäre diese einfach global änderbar, könnte irgendwo im Programm jemand auf die Idee kommen, das Alter auf -32 Jahre zu setzen. Solche Fehler sind nur schwer zu finden. Bei einem setter kann zumindest die Klasse eingreifen und verindern, dass ein negatives Alter gesetzt wird.

Globale Variable erschweren also Fehlersuche und erleichtern Spaghetti-Code


----------



## Tomate_Salat (5. Aug 2011)

Ich glaube, mit globale Variablen ist mehr soetwas gemeint:

```
public interface GlobalConfig {
    public String APP_NAME="Sampel App";
    public int DEFAULT_PORT=8080;
    public MyObject ANY_PROP=new MyObject("foo","bar");
}
```

auf welches man dann später so  zugreift:

```
JFrame frame=new JFrame(GlobalConfig.APP_NAME);
```


----------



## kossy (5. Aug 2011)

Besten Dank für die bisherigen Antworten! 

Wisst ihr vielleicht auch, wie ich globale Variablen besonders in einer nicht objektorientierten Programmiersprachen gänzlich vermeiden kann? 

Gibt es bei diesen Programmiersprachen überhaupt die Möglichkeit, ein solches Konzept zu vermeiden? Wenn ja, was wäre denn hier eine praxisnahe Möglichkeit?

Viele Grüße
Kossy


----------



## maki (5. Aug 2011)

> Wisst ihr vielleicht auch, wie ich globale Variablen besonders in einer nicht objektorientierten Programmiersprachen gänzlich vermeiden kann?


IMHO sind in prozeduralen Sprachen globale Variablen unvermeidbar, u.a. da es dort meistens keine Möglichkeit gibt Sichtbarkeiten einzuschränken.


----------



## DennisXX (5. Aug 2011)

maki hat gesagt.:


> IMHO sind in prozeduralen Sprachen globale Variablen unvermeidbar, u.a. da es dort meistens keine Möglichkeit gibt Sichtbarkeiten einzuschränken.



Das ist ja heftig, gibt es da wirklich keine Möglichkeit, auf diese Dinge zu verzichten? Aber nochmal explizit die Nachfrage: Warum sind gloable Variabeln so ungerne gesehen?

Greetz
Dennis


----------



## JD528 (5. Aug 2011)

Globale Variablen:

... lassen den Zustandsraum des Programms explodieren. Eine Berechnung, welche von einer globalen Variable abhängt, ist potenziell vom Zustand des gesamten Systems abhängig.
... sorgen für unberechenbare Nebenwirkungen quer durch den ganzen Programmcode. An irgendeiner Stelle wird eine globale Variable verändert, an irgendeiner ganz anderen Stelle geht infolge dessen der Code krachen. Viel Spaß bei der Fehlersuche!

Wenn du dir überlegst, wie riesig moderne Softwaresysteme sind, und wie wichtig und zeitaufwändig Fehlersuche und -behebung sind, wirst du vielleicht selbst sehen, dass man sich den Einsatz globaler Variablen schon gut überlegen sollte.


----------



## Landei (5. Aug 2011)

In puren funktionalen Sprachen (wie Haskell) gibt es keine veränderlichen Variablen, also höchstens "globale Konstanten", die normalerweise kein Problem darstellen (auch wenn man sie leicht vermeiden kann).


----------



## DennisXX (6. Aug 2011)

JD528 hat gesagt.:


> Wenn du dir überlegst, wie riesig moderne Softwaresysteme sind, und wie wichtig und zeitaufwändig Fehlersuche und -behebung sind, wirst du vielleicht selbst sehen, dass man sich den Einsatz globaler Variablen schon gut überlegen sollte.



Das ist mir schon klar, was Du da beschriebst und wo die Gefahren in der Verwendung von globalen Variablen liegen, aber die Frage ist, WIE kan ich sie in prozeduralen programmiersprachen überhaupt vermeiden. Auch wenn es hier nciht ins Forum passt, aber z.B. Access-VBA oder Excel-VBA sind Prachtbeispiele dafür, dass man irgendwann um globale Variablen in der Programmierung nicht drumherum kommt.

Greetz
Dennis


----------



## Wildcard (7. Aug 2011)

Tomate_Salat hat gesagt.:


> Ich glaube, mit globale Variablen ist mehr soetwas gemeint:
> 
> ```
> public interface GlobalConfig {
> ...


Mit Ausnahme von ANY_PROP ist das ein irreführendes Beispiel. Alle anderen sind Konstanten und gegen die ist erstmal nichts einzuwenden. Bei MyObject hängt es davon ab ob es immutable ist, oder nicht. Wenn es nicht immutable ist, dann ist es wirklich schlechter Stil.
Kleine Anmerkung am Rande und Geschmacksache, aber ich finde, wenn du das static Keyword weglässt, dann auch das public, denn so mischst du 2 Varianten.
Ich tendiere dazu sowohl public als auch static wegzulassen, da sie bedeutungslos sind.


----------



## Landei (7. Aug 2011)

Wie kommst du darauf, dass [c]static[/c] hier unwichtig wäre?  Mit [c]static[/c] kannst du [c]String s = GlobalConfig.APP_NAME;[/c] schreiben, ohne [c]static[/c] musst du von [c]GlobalConfig[/c] erben, um an die Konstanten heranzukommen.


----------



## ThreadPool (7. Aug 2011)

Landei hat gesagt.:


> [...], ohne [c]static[/c] musst du von [c]GlobalConfig[/c] erben, um an die Konstanten heranzukommen.



Nö musst du nicht. Genau wie Interface-Methoden implizit als "public abstract" definiert sind werden Konstanten automatisch als public static final angenommen. Man muss es nicht explizit hinschreiben.


----------



## oopexpert (28. Aug 2011)

Grundsätzlich: Es sind globale Konstanten und globale Variablen zu unterscheiden. Globale Konstanten sind bewusst global, haben aber keine Seiteneffekt, weil sie eben zur Programmlaufzeit konstant sind. Bei Variablen sieht das anders aus. Globale Variablen stinken förmlich nach schlechtem Design. Global bedeutet bei Variablen: Es gibt potentiell beliebig viele Code-Teile, die diese Variable verändern. Wenn man OO betrachtet, bedeutet dies, dass Objekte nicht MITEINANDER reden, sondern es wird über die Variable als Vermittler kommuniziert.

Noch eine Sache, die mich ein wenig ärgerlich macht: Interfaces, die zu Konstanten-Halter degradiert werden. 
Constant interface ist ein Anti-Pattern (Anti-pattern - Wikipedia, the free encyclopedia, Constant interface - Wikipedia, the free encyclopedia, Re: Constant Interface Antipattern)

Ich gehe davon aus, dass 

```
public interface GlobalConfig {
    public String APP_NAME="Sampel App";
    public int DEFAULT_PORT=8080;
    public MyObject ANY_PROP=new MyObject("foo","bar");
}
```
als schlechtes Beispiel gemeint war ;-)


----------



## CleanCoder (28. Aug 2011)

@oopexpert

Full ACK. Wer sowas macht, hat den Sinn von Interfaces nicht verstanden. Wenn dann zusätzlich zur Interface-Vergewaltigung noch allen Ernstes empfohlen wird, das "static final" wegzulassen (frei nach dem Motto: "Wer braucht schon verständlichen Code, welcher seine Intentionen verrät? Hauptsache 13 Zeichen gespart!"), kräuseln sich dem Freund des lesbaren Quellcodes endgültig die Fußnägel hoch.


----------



## Tomate_Salat (28. Aug 2011)

Wenn man weiß, wie ein interface Arbeitet, für den ist es auch kein Problem, soetwas zu lesen:

```
public interface ISample {
    int SOME_VAR=42;
    void doSomeThing(int flag);
}
```

@oopexpert: Ja, davon kannst du ausgehen. War ein Beispiel auf die schnelle, freitags, kurz vor der Mittagspause. Das es nicht das beste Beispiel war, hat ja Wildcard schon erklärt.


----------



## Marco13 (28. Aug 2011)

Stimmt, die Leute, die sich die WindowConstants (Java Platform SE 6) ausgedacht haben, haben echt null Plan von Java :joke: 
Aber es stimmt schon: Alles, was global und statisch ist, gehört kritischst hinterfragt, und auf diese Idee mit dem Interface würde ich nicht kommen. Der Sinn erschließt sich mir nicht ganz. Aber ist vielleicht nicht so wichtig.


----------



## oopexpert (28. Aug 2011)

Marco13 hat gesagt.:


> Stimmt, die Leute, die sich die WindowConstants (Java Platform SE 6) ausgedacht haben, haben echt null Plan von Java :joke:
> Aber es stimmt schon: Alles, was global und statisch ist, gehört kritischst hinterfragt, und auf diese Idee mit dem Interface würde ich nicht kommen. Der Sinn erschließt sich mir nicht ganz. Aber ist vielleicht nicht so wichtig.



WindowsConstant ist aus den Anfängen von JAVA. 1998 wurde Swing eingegliedert in JAVA 1.2:
Swing (Java) ? Wikipedia

Da bestand dieses Interface schon:
Java Platform 1.2 API Specification

JAVA hatte 1996 sein erstes Release. Ich bescheinige den Leuten, die Swing entwickelt haben keine Inkompetenz, aber man darf durchaus die Erfahrung der Personen in der Entwicklung mit JAVA in Zweifel ziehen.


----------



## Marco13 (28. Aug 2011)

Ich finde das mit den Interface jetzt nicht sooo "schlimm": Ob man Konstanten nun in einer abstrakten Klasse oder einem Interface schreibt, macht so gesehen von der reinen Verwendung her eigentlich nicht so viel Unterschied. Der gravierendste Unterschied ist, dass das Interface falsch verwendet werden kann: Damit können diese Konstanten problemlos in irgendwelche beliebigen Klassen "mit-rein-vererbt" werden (und DAS ist dann das _eigentliche_ "Antipattern"). Bei einer abstrakten Klasse mit privatem Konstruktor wäre das nicht möglich.


----------



## CleanCoder (28. Aug 2011)

Tomate_Salat hat gesagt.:


> Wenn man weiß, wie ein interface Arbeitet, für den ist es auch kein Problem, soetwas zu lesen:
> 
> ```
> public interface ISample {
> ...


Nun, mit der Argumentation kann man (um es mal überspitzt zu formulieren) auch die berühmten Perl-Einzeiler als "problemlos zu lesen" bezeichnen. Schließlich ist es ja alles mit der Arbeitsweise der Sprache erklärbar ...

Also noch mal zur Erklärung, was ich überhaupt sagen will: Es geht um die Lesbarkeit des Codes. Ich halte ehrlich gesagt das implizite Umwandeln von 

```
public interface ISample {
    int SOME_VAR=42;
}
```
zu

```
public interface ISample {
    static final int SOME_VAR=42;
}
```
für einen Designfehler, den die Java-Designer heute vielleicht nicht mehr so machen würden. Wenn wir für einen Moment annehmen, dass wir die Eigenarten von Java nicht kennen würden, dann suggeriert das erste Interface, dass alle Klassen und ihre Instanzen, die dieses Interface implementieren, von diesem eine Property vom Typ int übernehmen, welche den Default-Wert 42 hat. Und nicht, dass das nur eine verkappte Klassenkonstante ist. Dann kann man den ganzen Spaß nämlich sparen und gleich die klassische Variante nehmen, also Klasse mit privatem Konstruktor und einer Anzahl von statischen Konstanten.


----------



## CleanCoder (28. Aug 2011)

Marco13 hat gesagt.:


> Stimmt, die Leute, die sich die WindowConstants (Java Platform SE 6) ausgedacht haben, haben echt null Plan von Java :joke:


Das ist doch billige Polemik. Niemand hat behauptet, dass sie "null plan" haben, aber die Java-API ist nunmal auch nichts "Gottgegebenes", welches einmal richtig gemacht wurde und dann nie mehr kritisiert werden darf! Die damaligen Designentscheidungen wurden 1. von Menschen und 2. mit dem damaligen Kenntnisstand getroffen. Wenn alle Entscheidungen von allen Designern aller Programmiersprachen immer richtig und über alle Kritik erhaben wären, dann hätte es wohl nie das Software-Enginnering als eigenständige Forschungsdisziplin gegeben, und wir könnten auch unsere heutigen komplexen Systeme als Assembler-Code in den PC hämmern.


----------



## maki (28. Aug 2011)

Konstanten in ein Interface zu hämmern (aka Constant Interface Antipattern) ist sehr unschön, läuft dem eigentlichen Zweck von Interfaces zu 100% zuwider, da werden keine Schnittstellen vereinbart, schlimmer wird es nur noch wenn man dann noch so ein "Interface" _implementiert_, die Konstanten wird man u.a. nie mehr los in der Vererbungshierarchie, für sowas gibt es static imports, wurden genau für sowas eingeführt.

Ansonsten hate ich den Begriff "Spftware Engineering" für ein Blähwort aus 'ner Marketing Abteilung, Programmieren ist ein Handwerk, auch laut Uncle Bob


----------



## Marco13 (28. Aug 2011)

@CleanCoder: Polemik (oder eher Sarkasmus) wäre es ohne den :joke:


----------

