AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Vermeiden von globalen Variablen

Ein Thema von Scurra · begonnen am 13. Feb 2015 · letzter Beitrag vom 18. Feb 2015
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

AW: Vermeiden von globalen Variablen

  Alt 13. Feb 2015, 22:54
Um mal allgemein zu antworten. Globale Variablen wird man am ehesten los, wenn man mit Klassen arbeitet. Dort können die Werte mit Hilfe von privaten Feldern gut den einzelnen Methoden zu Verfügung gestellt werden. Im Konstruktor werden sie zu gewiesen/belegt und stehen dann den Methoden zur Verfügung.

Denk eventuell mal in diese Richtung.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Scurra

Registriert seit: 19. Jan 2015
81 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Vermeiden von globalen Variablen

  Alt 14. Feb 2015, 09:21
Danke für die Antworten! Das hilft mir schon einmal weiter.

Zitat:
Im Form erzeugst du dann kein TPanel sondern eben einen solchen Frame (Frame-Unit in Uses aufnehmen) und platzierst ihn an die passende Stelle. Hier wäre eventuell ein TFlowPanel als Parent brauchbar, das sich automatisch um die fließende Anordnung kümmert. Das würde deinen Code sicher deutlich reduzieren.
Nur um zu überprüfen, ob ich das auch richtig verstanden habe: Was ich in Form einer Klasse umsetzen wollte, würde dann durch einen Frame ersetzt, indem ich das Layout festlege. Am Montag werde ich mir das mal anschauen, auch wenn ich wahrscheinlich bei meiner Klasse bleibe, allein deshalb, um das Erstellen von Klassen zu üben.

Zitat:
Um mal allgemein zu antworten. Globale Variablen wird man am ehesten los, wenn man mit Klassen arbeitet. Dort können die Werte mit Hilfe von privaten Feldern gut den einzelnen Methoden zu Verfügung gestellt werden. Im Konstruktor werden sie zu gewiesen/belegt und stehen dann den Methoden zur Verfügung.
Ok, das war auch eine meiner Ideen. Bleibt noch eine Sache: Am liebsten würde ich in meiner Klasse auch schon programmieren, was passieren soll, wenn ich z. B. auf eines der Panels klicke. In meinem Code sieht das bisher so aus:

Code:
procedure TfrmMain.SelectByClick(Sender: TObject);
var
  obj   : TPanel;
  pnlIdx : Integer;
begin
  obj := Sender as TPanel;
  if GetKeyState(VK_Control) < 0 then // Strg pressed; enable multiselect
  begin
    if obj.Color = selectedPnlColor then obj.Color := defaultPnlColor
    else obj.Color := selectedPnlColor;
  end
  else // Strg not pressed; disable multiselect
  begin
    for pnlIdx := 0 to Length(panelsArray) -1 do
    begin
      panelsArray[pnlIdx].Color := defaultPnlColor;
    end;
    obj.Color := selectedPnlColor;
  end;
end;
Ähnlich wie im Explorer von Windows möchte ich, dass selektierte Panels blau (selectedPnlColor) werden. Wenn nun schon andere Panels selektiert sind, dann sollen diese Panels nach einem Klick wieder die Standardfarbe (defaultPnlColor) bekommen (falls STRG nicht gedrückt wird). Wie im Code oben zu sehen, greife ich hierzu auf panelsArray zu, das array of TPanel, das alle Panels in meiner Scrollbox enthält.
Wenn ich eine solche Prozedur in meiner Klasse implementieren möchte, dann brauche ich also in meiner Klasse schon ein array in Form einer Klassenvariablen. In diesem Fall hätte ich vmtl. kein Problem, die Prozedur zu implementieren. Aber das schränkt meine Klasse dafür stark ein. Ich kann in meinem Projekt ohne Weiteres nur eine Scrollbox mit Panels erzeugen. Ist es in meinem Fall sinnvoll, das array als Klassenvariable zu definieren oder gibt es noch andere Möglichkeiten, um die Prozedur im Code-Beispiel oben auch ohne Klassenvariable innerhalb meiner Klasse zu implementieren.

Vielleicht beantworte ich meine Frage jetzt schon selbst, aber als ich den Beitrag geschrieben habe, kam mir die Idee, meiner Klasse TIconPanel eine weitere Eigenschaft mitzugeben, z. B. ein Integer FGroupIndex. Dann könnte ich IconPanels, die zusammen gehören sollen, allen den gleichen Gruppen-Index verpassen und so aus allen Panels im array die heraussuchen, die einen bestimmen Wert bei FGroupIndex haben.

P.S.: Zusammenfassend kann man vllt. sagen, dass meine "Probleme" neben meiner fehlender Erfahrung auch daher kommen, dass ich mich nicht entscheiden kann, ob ich meine Klasse allgemein halten möchte oder spezieller machen möchte. Ist sie allgemein, dann kann ich die Klasse für viele verschiedene Anwendungen verwenden, dafür erledigt die Klasse wenig Arbeit für mich. Implementiere ich die Klasse hingegen eher spezieller, dann bin ich bei der Verwendung stärker eingeschänkt, aber dafür erledigt die Klasse schon fast alles für mich.
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#3

AW: Vermeiden von globalen Variablen

  Alt 14. Feb 2015, 10:07
Zitat:
P.S.: Zusammenfassend kann man vllt. sagen, dass meine "Probleme" neben meiner fehlender Erfahrung auch daher kommen, dass ich mich nicht entscheiden kann, ob ich meine Klasse allgemein halten möchte oder spezieller machen möchte. Ist sie allgemein, dann kann ich die Klasse für viele verschiedene Anwendungen verwenden, dafür erledigt die Klasse wenig Arbeit für mich. Implementiere ich die Klasse hingegen eher spezieller, dann bin ich bei der Verwendung stärker eingeschränkt, aber dafür erledigt die Klasse schon fast alles für mich.
Tendenziell würde ich (aus Erfahrung) sagen: Stelle deine aktuellen Anforderungen zusammen, und dann mach' die Klassen eher spezieller. Oft kommt man dann an Punkte, bei denen man die Klasse etwas allgemeiner machen könnte, "falls es dann irgendwann doch erweitert wird". Mach' das nicht, denn das passiert fast nie. Zumindest nicht in dem Bereich, den du vorher antizipierst

Klar, deine Anforderungen werden sich ändern. Aber meistens sind das dann inkrementelle Änderungen (xyz soll hier ne Spezialbehandlung bekommen, also ein Feature wie "Wenn jemand Freitag den 13. im Kalender auswählt, soll hier ein roter Warnhinweis erscheinen") und nicht solche Sachen wie "Wir möchten eine Datenbank in der man in einem bestimmten Format Warnungsregeln für beliebige Kalendertage definieren kann." - so eine Anforderung ist meistens früh bekannt.

Und wenn du vorzeitig "universell einsetzbaren" Code schreibst, dann sind in deiner Anwendung viele Stellen, in denen du dann wieder einen Spezialfall bauen musst. An der Stelle sieht das dann umständlich aus.

Wenn du etwas vielleicht in anderen Projekten auch mal brauchen kannst, dann programmiere das erst mal so, dass es aktuell passt. Für das andere Projekt kannst du ja die Klasse kopieren und erweitern (wenn du genau weißt, was für eine Erweiterung du jetzt brauchst).

Geändert von jfheins (14. Feb 2015 um 10:24 Uhr)
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.740 Beiträge
 
Delphi 6 Enterprise
 
#4

AW: Vermeiden von globalen Variablen

  Alt 18. Feb 2015, 10:40
Delphi-Quellcode:
if obj.Color = selectedPnlColor then obj.Color := defaultPnlColor
else obj.Color := selectedPnlColor;
Dies sieht ja so aus, als ob du über die Panel-Farbe feststellst, ob eine Datei (für die ja das Panel steht) selektiert ist oder nicht. Hier in der DP wird dir sicher noch sehr oft gepredigt (nicht negativ gemeint) werden, dass es sinnvoll ist, die Logik von der Darstellung zu trennen. Hier könnte das so aussehen, das du unabh. von der GUI eine Liste von Klassen hast, jede steht für eine Datei und in der Klasse könnte es eine Eigenschaft Selected geben. Oder du hast eine Liste aller Klassen/Dateien und eine in der die selektierten Klassen/Dateien stehen.
Wird nun in der GUI geklickt schaust du welche Datei/Klasse dies betrifft. Schaust ob sie bereits selektiert ist oder nicht und änderst diesen Zustand entsprechend.
Anschließend wird die GUI "refreshed".
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Vermeiden von globalen Variablen

  Alt 18. Feb 2015, 10:49
@Jumpy & TE

Gerade in Bezug auf die Controls wird hier explizit gepredigt, dass diese Controls zur Darstellung eines Status sehr wohl geeignet sind aber eben nicht um den Status-Wert dort abzulesen bzw. als Status-Speicher zu missbrauchen.

Daten präsentieren: Ja
Daten speichern: Nein

Grund:

Die Präsentation ist immer eine Interpretation von Daten. Um von dem interpretierten und präsentierten Wert wieder auf den Ursprungswert zu kommen ist durch die Brust ins Auge, aufwändig und somit auch extrem fehleranfällig.

Eine Liste mit den echten Informationen und diese Liste einfach in den Controls abbilden ist erheblich einfacher, als von dem Control wieder die richtigen Daten heraus zu interpretieren.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (18. Feb 2015 um 10:53 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:18 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz