Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Globale Variablen pro/contra


jaenicke - Do 10.03.11 16:49

Moderiert von user profile iconMartok: Diskussion abgetrennt von [url=http://www.delphi-forum.de/viewtopic.php?t=104495]hier[/url]

Und noch besser ist es, gleich ein ordentliches Konzept zu machen, denn fast immer sind globale Variablen erstens fehleranfällig und zweitens unnötig, jedenfalls was einzelne Werte angeht... :roll:


trm - Do 10.03.11 21:56

Hallo Sebastian,

"unnötig".
Hm, ich denke, das trifft es nicht.
In ernsthaften Projekten ist es m.M. nach erforderlich, wenn Procedureübergreifend, globale Variablen zu nutzen.

Oder programmierst Du immer, um dieses Problem zu umgehen, eine eigene Function, mit der Du die Variablen "zwischenspeicherst" - und das für JEDE Variable, die in anderen Proceduren benötigt wird?

Wie auch immer, persönlich interessiert es, wie Du das Problem löst.

Danke + Gruß
Mathias


jaenicke - Do 10.03.11 22:05

Ich programmiere in der Regel objektorientiert. Einzelne Funktionen oder Prozeduren nutze ich nur für kleine atomare Einzelprobleme. Und die haben dann ein paar Parameter, aber nicht zu viele.

Auf diese Weise lässt sich der Quelltext auch sehr gut wiederverwenden. Alles was irgendwie allgemeinen Nutzen hat, stecke ich in entsprechende Units. Entsprechend kommentiert selbstverständlich. Das können wir dann alle nutzen, so dass nicht so viel redundanter Code entsteht.

Außerdem wird der Code so stabiler, da die einzelnen Funktionen gut getestet sind. (Und eben nicht von globalen Variablen abhängen usw., von denen dann niemand weiß wo die befüllt werden usw.)


trm - Do 10.03.11 22:52

Jaja, meine Rede.

Hier mal ein Beispiel:

In der OnMouseOver Procedure bei einem Stringgrid kann man ermitteln, in welcher Zelle der Mauszeiger schwebt. Das muss dann eigentlich zum weiternutzen z.B. in OnDrawCell vom Stringgrid ausgewertet werden.

Lösung 1: X und Y von OnMouseMove weitergeben - per globaler Variable (oder per Object, z.B. Tag)
Lösung 2: Gleich ausrechnen und diese Werte (auch 2) weitergeben - per globaler Variable.
Lösung 3: Eigenes OnDrawCell als Procedure erstellen als Override und zwei Parameter extra einfügen, dann in OnMouseCell diese Procedure über eine Function anspringen?

Ich glaube, das ist doch eine gute lösung in dem Fall, eine globale Variable zu nutzen?

Bitte zeige mir einen Weg, der keine globale Variable benötigt. Ich lerne gern dazu :)

Viele Grüße
~Mathias


jaenicke - Do 10.03.11 22:58

Naja, wenn du fälschlicherweise private Felder mit globalen Variablen meinst, dann ist das schon gut so... Das ist aber ein Unterschied.

So ist es objektorientiert und passend, als privates Feld:

Delphi-Quelltext
1:
2:
3:
4:
5:
type
  TFormX = class(TForm)
  private
    FLastMousePos: TPoint;
  ...
Wobei das hoffentlich nur ein Beispiel war, hier brauchst du dir die Werte ja nicht merken. ;-)


trm - Do 10.03.11 23:53

Und was ist jetzt der Unterschied zur Globalen Definition eines Tpoint?


jaenicke - Fr 11.03.11 00:03

Dass es an das Objekt gebunden ist. Wenn du also z.B. zwei gleiche Formulare hast, hast du auch zwei solche Felder.

Zudem kann es nur von innerhalb des Objektes erreicht werden. Es ist also ganz klar wo darauf zugegriffen werden kann. Man muss also nicht lange suchen wo und wann die Variable befüllt und wo überall benutzt wird.


Martok - Fr 11.03.11 01:17

Und noch ein Vorschlag, der zu Separation of Concerns passt: "Hebe eine Zelle hervor, wenn die Maus darüber ist" oder auch "in OnDrawCell per ScreenToClient(Mouse.CursorPos) die Mausposition holen" und gar keine externe Variable brauchen ;)

Hat auch den Vorteil, dass man nicht erst überlegen muss woher diese Variable denn nun kommen könnte und ob da vielleicht noch irgendwelche Offsets oder so schon eingerechnet sind.

Als krasses Gegenbeispiel, wie man es nicht machen sollte (auch wenn ich sowas nicht gerne mache): das Globus-Programm [http://www.delphi-forum.de/viewtopic.php?t=104424] nebenan. Völlig unlesbar ;)


Aber darum ging es ja nun eigentlich gar nicht, also... Ende hier oder, sollte noch Bedarf bestehen: Meldung an den VA, dann kann die allgemeine Diskussion hier abgetrennt und einzeln fortgeführt werden.


trm - Fr 11.03.11 01:17

Danke.

Wäre es dann nicht aber doch sinnvoller (so, wie ich es auch handhabe), eine eigene Unit anzulegen, in der die Variablen liegen?
Der Vorteil wäre doch wesentlich in Form von Übersichtlichkeit und, wie Du selbst sagtest: Wiederverwertbarkeit.
Das gleiche mache ich auch mit Globalen Konstanzen.

Aber, ich denke, das ist wieder etwas, was jeder für sich selbst entscheidet, es gibt hier nicht unbedingt ein einheitliches Schema, welches besonders gut oder schlechter ist. Je nachdem, wie der Programmierer es für sich selbst gut findet.

Bis bald :)


Edit: 2 Rechtschreibfehler gefunden.


vagtler - Fr 11.03.11 11:23

Langsam wird es doch Zeit für einen eigenen Thread... ;)

user profile icontrm hat folgendes geschrieben Zum zitierten Posting springen:
[...] Wäre es dann nicht aber doch sinnvoller (so, wie ich es auch handhabe), eine eigene Unit anzulegen, in der die Variablen liegen? [...]

Da hast Du das Problem nur verlagert.

Zitat:
[....] Der Vorteil wäre doch wesentlich in Form von Übersichtlichkeit und, wie Du selbst sagtest: Wiederverwertbarkeit. [...]

Du hast den Müll nur an einer anderen Stelle. Mit OOP hat das nichts zu tun.

Zitat:
[...] Aber, ich denke, das ist wieder etwas, was jeder für sich selbst entscheidet, es gibt hier nicht unbedingt ein einheitliches Schema, welches besonders gut oder schlechter ist. Je nachdem, wie der Programmierer es für sich selbst gut findet. [...]

Drücken wir es mal ganz diplomatisch aus: wenn einer meiner Entwickler eine globale Variable einführen würde, dürfte er umgehend bei mir antanzen und sollte eine verdammt gute Begründung für den Verstoß gegen jegliche Prinzipien moderner Softwareentwicklung in der Tasche haben - oder sich direkt einen neuen Job suchen... :mrgreen: