![]() |
Globale Variablen richtig nutzen
Hallo Zusammen,
Ich habe ein großes Projekt und an verschiedenen Stellen im Programm muss ich auf "allgemeine Einstellungen" zu greifen - solche Dinge wie: Datenbankeinstellungen, oder andere Dinge die ich mir "merken" möchte. Dies sind lediglich einfache Datentypen wie Integer oder Strings. Wie implementiere ich dies in Delphi am Besten? Nutze ich einfach eine Unit, in der ich öffentliche Variablen (ob jetzt direkt oder per Getter Setter sei mal dahin gestellt) deklariere und nutze. Oder sollte ich dies über ein Singleton-Pattern machen, oder liefert Delphi vielleicht schon eine Art "Grundfunktion" mit, die ein solches Management übernehmen kann? Manche Variablen werden während der Laufzeit ermittelt und können sich auch ändern. |
AW: Globale Variablen richtig nutzen
Das ist reine Geschmacksache.
Es sollten möglichst Verwechslungen ausgeschlossen werden. Wenn Du
Delphi-Quellcode:
irgendwo global ablegst besteht die Gefahr, dass Du irgendwo mal versehentlich auf ein lokales I zugreifen willst, aber die lokale Deklaration vergisst und somit die globale Variable benutzt.
I: Integer = 0;
In dem Fall wäre vielleicht global_I schon sinnvoller. Du kannst auch (mit etwas neueren Delphiversionen) eine Klassenvariable nutzen:
Delphi-Quellcode:
und so benutzen:
TGobals = class
class var I: Integer; end;
Delphi-Quellcode:
So hat man etwas mehr Ordnung in den Units.
X := TGlobals.I;
Ein Singleton ist sinnvoll, wenn man Objekte bei Bedarf einmalig erstellen lässt und dann künftig immer diese Instanz verwendet. Das hilft Dir bei einfachen Typen nicht. |
AW: Globale Variablen richtig nutzen
Zitat:
Mit älteren Delphi-Versionen dementsprechend
Delphi-Quellcode:
type
TGlobals = packed record I: Integer; end; var aGlobals: TGlobals; // Benutzung X := aGlobals.I; |
AW: Globale Variablen richtig nutzen
Hab' mir für diese "Problem" mal 'ne Komponente gebaut, die so diverses Konfigurationsgedöns selbständig ermittelt bzw. speichert bzw. die vom Anwender gemachten Angaben per Setter annimmt und speichert und beim Neustart des Programmes restauriert.
Auf alles kann per Property zugegriffen werden. Jedes Programm bekommt auf's MainForm die Komponente gepappt und schon ist das Grundgerüst fertig. Ein paar Sachen kann man dann im Objektinspektor anpassen, soweit erforderlich. |
AW: Globale Variablen richtig nutzen
Zitat:
Delphi-Quellcode:
Falls du mit
type
TSettings = record strict private class var Ini: TIniFile; strict private // Setter und Getter public class constructor Create; // Ini erzeugen und Einstellungen laden class destructor Destroy; // Einstellungen speichern und Ini freigeben public property Setting1; property Setting2; // .. end;
Delphi-Quellcode:
bzw.
class constructor
Delphi-Quellcode:
nicht vertraut bist: Diese Methoden werden automatisch einmalig aufgerufen (sofern die Klasse irgendwo im Code referenziert wird) und zwar erfolgt
class destructor
Delphi-Quellcode:
beim Programmstart und
Create
Delphi-Quellcode:
kurz vor Beendigung. So ähnlich wie die
Destroy
Delphi-Quellcode:
und
initialization
Delphi-Quellcode:
Abschnitte in Units.
finalization
|
AW: Globale Variablen richtig nutzen
Den Anwendungskern solltest du immer so realisieren, dass nicht direkt auf globale Variablen zugegriffen wird. Nur so kann dieser unabhängig von der Anwendung getestet werden. Dafür bietet sich z.B. eine Schnittstelle an, die nur die Aufgabe hat solche Umgebungsvariablen bereitzustellen.
Beispiel:
Delphi-Quellcode:
Erzeugen des Anwendungsfalls in der Anwendung:
interface
IAnwendungsfall1Config = Interface(IInterface) [GUID] function GetSetting1: Integer; procedure SetSetting1(AValue: Integer); function GetSetting2: string; property Setting1: Integer read GetSetting1 write SetSetting1; property Setting2: string read GetSetting2; end; TAnwendungsfall1Config = class(IAnwendungsfallConfig) constructor Create(var ASetting1: Integer; const ASetting2: string); private FSetting1: PInteger; FSetting2: string; public function GetSetting1: Integer; procedure SetSetting1(AValue: Integer); function GetSetting2: string; end; TAnwendungsFall1 = class() constructor Create(const AConfig: IAnwendungsfallConfig; const AFileApi: IFileApi; const ADbFramwork: IDbFramwork); private FConfig: IAnwendungsfallConfig; FFileApi: IFileApi; FDbFramwork: IDbFramwork; public procedure TuWas; end; implementation constructor TAnwendungsfall1Config.Create(var ASetting1: Integer; const ASetting2: string); begin FSetting1 := @ASetting1; FSetting2 := ASetting2; end; function TAnwendungsfall1Config.GetSetting1: Integer; begin Result := FSetting1^; end; procedure TAnwendungsfall1Config.SetSetting1(AValue: Integer); begin FSetting1^ := AValue; end; function TAnwendungsfall1Config.GetSetting2: string; begin Result := FSetting2; end; constructor TAnwendungsFall1.Create(const AConfig: IAnwendungsfallConfig; const AFileApi: IFileApi; const ADbFramwork: IDbFramwork); begin inherited Create; FConfig := AConfig; FFileApi := AFileApi; FDbFramwork := ADbFramwork; end; procedure TAnwendungsFall1.TuWas; begin FConfig.Setting1 := FFileApi.TuWas(FConfig.Setting1); FDbFramwork.TuWas(FConfig.Setting2); end;
Delphi-Quellcode:
Im Testprojekt würde man beim Erzeugen für jeden Testfall eigene Variablen nutzen und die API simulieren.
Config := TAnwendungsfall1Config.Create(GlobaleVariable1, GlobaleVariable2);
AnwendungsFall1 := TAnwendungsFall1.Create(Config, GlobalFileApi, GlobalDbFramwork); |
AW: Globale Variablen richtig nutzen
Zitat:
|
AW: Globale Variablen richtig nutzen
Zitat:
|
AW: Globale Variablen richtig nutzen
Zitat:
Meiner Meinung nach ist das überhaupt nicht global, da z.B. der Oberfäche es vollkommen egal (sein muß) welche Datenbank wie angesprochen wird. Gruß K-H |
AW: Globale Variablen richtig nutzen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:19 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