AGB  ·  Datenschutz  ·  Impressum  







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

Programmeinstellungen organisieren

Ein Thema von Blamaster · begonnen am 27. Okt 2014 · letzter Beitrag vom 29. Okt 2014
Antwort Antwort
Seite 1 von 2  1 2      
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#1

Programmeinstellungen organisieren

  Alt 27. Okt 2014, 21:37
Delphi-Version: 7
Hi,

ich versuche gerade den Code eines älteren Projekt ein wenig neu zu organisieren. Konkretes Ziel ist eine striktere Trennung von Gui <-> Logik.
Soweit klappt das auch alles schon so wie es soll.

Jetzt stehe ich allerdings vor dem Problem das ich gerade keien Idee habe wie man Einstellungen am besten verwaltet ohne dabei die bisher sauber getrennten Klassen wieder "verunstalten" zu müssen.

Folgendes Scenario:

Delphi-Quellcode:
Klasse A:
  property enableHighlighting: boolean read FenableHighlighting write FenableHighlighting;
  property enableLog: boolean read FEnableLog write FEnableLog;

Klasse B:
  property autoOpen: boolean read FautoOpen write FautoOpen;
Im Hauptformular wird jeweils eine Instanz von KlasseA und KlasseB erzeugt. Zusätzlich erzeugt das Hauptformular dynamisch ein Einstellungs-Form.

Variante 1: Damit das Einstellungsformular direkt Änderungen an den settings der Objekte vornehmen kann müssten diese im Einstellungs-Form bekannt sein, sprich das Einstellungsform müsste auf die Objektinstanzen im Hauptformular zugreifen können -> unschön, abhängigkeiten usw.

Variante 2: Das Einstellungsformular mit getter und setter für die jeweiligen Objekte versehen und die Objekte dann sozusagen zur Laufzeit an die Einstellungs-Form übergeben -> fühlt sich auch merkwürdig an

Variante 3: Das Einstellungs-Fenster als reines Eingabe-Fenster benutzen, sprich getter und setter für die ganzen Checkboxen, Edit, ... und dann im Hauptformular die Werteübergabe an die verschiednene Objekte machen -> bläht den Code im Hauptformular ziemlich stark auf

Mir fallen noch ein paar weitere Varianten ein die sind aber auch nicht besser als die oben genannten.

Wie würdet ihr das sauber lösen ?
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#2

AW: Programmeinstellungen organisieren

  Alt 27. Okt 2014, 23:06
Ich finde Variante 1 gar nicht so schlimm, wenn klar ist, wem die Objekte gehören: dem Hauptformular. Das Einstellungsformular wird nach den Objekten erstellt und bekommt Referenzen darauf im Konstruktor übergeben. Das Hauptformular zerstört die Objekte erst wieder, wenn es bereits das Einstellungsformular zerstört hat.

EDIT: Ich merk gerade, das man Variante 1 auch anders interpretieren kann. Das Einstellungsformular sollte keine Abhängigkeit von dem Hauptformular haben, sondern nur von den beiden Einstellungsobjekten.

Geändert von BUG (27. Okt 2014 um 23:10 Uhr)
  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
 
#3

AW: Programmeinstellungen organisieren

  Alt 27. Okt 2014, 23:28
Einfach ein Repository für die Einstellungen
Delphi-Quellcode:
ISettingsRepository = interface
  function GetBool( const Section, Ident : string; Default : Boolean = False ) : Boolean;
  procedure SetBool( const Section, Ident : string; Value : Boolean );
  ...
end;
und konkretisieren für wo auch immer man das speichern möchte (INI, Registry, Datenbank, ...)

Dieses Repository gibt man dann einfach den Einstellungs-Klassen mit
Delphi-Quellcode:
TKlasseA = class
private
  FSettingsRepository : ISettingsRepository;
  FSection : string; // Path + ClassName?? Wie auch immer organisieren
  function Get_enableHighlighting : Boolean;
  procedure Set_enableHighlighting( Value : Boolean );
public
  constructor Create( SettingsRepository : ISettingsRepository; const Path : string );
  property enableHighlighting: boolean read Set_enableHighlighting write Get_enableHighlighting;
  ...
end;

function TKlasseA.Get_enableHighlighting : Boolean;
begin
  Result := FSettingsRepository.GetBool( FSection, 'enableHighlighting' );
end;

procedure TKlasseA.Set_enableHighlighting( Value : Boolean );
begin
  FSettingsRepository.SetBool( FSection, 'enableHighlighting', Value );
end;
Für den Einstellungsdialog hat man nun Zugriff auf das Repository und zwar völlig unabhängig von den einzelnen Klassen.
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)
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#4

AW: Programmeinstellungen organisieren

  Alt 28. Okt 2014, 13:44
Das würde aber bedeuten das ich dieses Interface so in jeder Klasse implementieren müsste für die in irgendeiner Form Einstellungen gespeichert werden müssen.

Das widerspricht aber dem reuse/modularen Gedanken. Zum einen würde ich dem Anweder der ClassA aufzwingen wie er das speichern/behandeln von settings zu machen hat, zum anderen müsste ich Fremdklassen die das Interface nicht implementieren entweder dahingehend abändern oder eine Wrapperklasse drüber setzen. Da könnte man dann auch gleich ein großes Settingsobjekt erstellen und per Constructor sowohl an die KlasseA, KlasseB und das Einstellungsformular übergeben. (Genau das ist aber hinsichtlich der Trennung vom eigentlichen Objekt und dem speichern/verwalten von Einstellungen nicht gewollt)
  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: Programmeinstellungen organisieren

  Alt 28. Okt 2014, 14:21
Das würde aber bedeuten das ich dieses Interface so in jeder Klasse implementieren müsste für die in irgendeiner Form Einstellungen gespeichert werden müssen.
Äh, wie, nee ... du benutzt das Interface in jeder Einstellungsklasse implementiert wird das nur einmal.

Und die Einstellungen hast du doch auch nicht pro Klasse in einer Datei vorliegen, oder doch?
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)
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#6

AW: Programmeinstellungen organisieren

  Alt 28. Okt 2014, 15:57
Hi,

was ist bei dir die genaue Definition von Einstellungsklasse ?

Nehmen wir besser ein anschauliches Beispiel. Wir haben eine Klasse die eine Datenbankverwaltung enthält und nennen die Klasse "TMyDatabase" diese Klasse hat jetzt die propertys "databaseName" und "databasePassword". Das sind die beiden Einstellungen die von "außen" also außerhalb der Klasse TMyDatabase gespeichert werden sollen.

Das speichern soll über Einträge in einer "settings.ini" erfolgen.

Eine Instanz also ein Objekt von TMyDatabase wird jetzt im constructor des Hauptformular "frmMain" erzeugt und im destructor wieder freigegeben.

Über ein eigenständiges Einstellungsfenster soll mithilfe von 2 Editfeldern nun das Passwort und der Datenbankname im Datenbankobjekt gesetzt werden.

Durch obiges Beispiel entstehen jetzt 2 Fragen/Probleme:
1. Wie werden die Daten der Editfelder im Einstellungsformular an die konkrete Instanz von TMyDatabase übergeben welche ja in frmMain erzeugt wurde und somit im Einstellungsformular erstmal nicht bekannt ist
2. Wie kann das speichern der Einstellungswerte außerhalb des TMyDatabase Objekt erfolgen.

Wenn ich es richtig verstanden habe würdest du bei dem vorgeschlagenen Ansatz nun in TMyDatabase das Interface "ISettingsRepository" einbinden. Das Einstellungsformular kennt dann lediglich das Interface ISettingsRepository nicht aber die Instanz oder überhaupt die Klasse TMyDatabase.

Das würde ja aber bedeuten das ich das Interface ISettingsRepository in der TMyDatabase Klasse einbinden müsste.

Und an der Stelle geht dann doch der Gedanke unabhängiger Module verloren. Der Sinn objektorientiert zu programmieren ist doch sinvolle Dinge zu einer Klasse zusammen zu führen unter anderem mit dem Hintergedanken der Wiederverwendbarkeit. (Kapselung in eigenständige unahängige Module)

Würde ich jetzt ISettingsRepository in TMyDatabase implementieren und die Klasse anschließed an einen Kollegen/Mitarbeiter/Community/Opensource weitergeben, dann zwinge ich den nachfolgenden Anweder das ISettingsRepository zu verwenden und zwar unabhängig davon wie er in seinem bisherigen Projekt in dem die Klasse nun eingesetzt werden soll das speichern der Einstellungen realisiert wurde.

Oder um es weiter zu führen neben TMyDatabase verwende ich zusätzlich die Fremdkomponente "TVirtualStringTree". Spezifische Einstellungen von VirtualStringTree sollen nun ebenfalls gespeichert werden. Das würde doch konkret bedeuten das ich auch in der fremden Klasse ISettingsRepository einbinden müsste und diese dem Interface auch genügen müsste.
  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
 
#7

AW: Programmeinstellungen organisieren

  Alt 28. Okt 2014, 16:02
Dann zeig doch mal wie du das bisher machst ... dann kann ich dir die Unterschiede so erläutern, dass du es auch verstehst

Also zeige doch einmal konkret an dem Beispiel von TMyDatabase und dem TVirtualStringTree wie du da aktuell die Einstellungen speicherst.

Ich hoffe ja nicht, dass du überall verteilt sowas wie TIniFile.Create('xxx.ini'); stehen hast.
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)
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#8

AW: Programmeinstellungen organisieren

  Alt 28. Okt 2014, 17:02
Okay hier ein Beispiel mit Code.

frmMainU:
Delphi-Quellcode:
unit frmMainU;

interface

uses
  frmSettingsU, DatabaseU, VirtualTrees, IniFiles, ....;

type
  TfrmMain = class(TForm)
    btnSettings: TButton;
    vst: TVirtualStringTree;
    procedure btnSettingsClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;
  database: TMyDatabase;

implementation

{$R *.dfm}

procedure TfrmMain.btnSettingsClick(Sender: TObject);
var
  frmSettings: TfrmSettings;
begin
  frmSettings := TfrmSettings.Create(nil);
  try
    frmSettings.ShowModal;
  finally
    frmSettings.Free;
  end;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
var
  ini: TInifile;
begin
  database := TMyDatabase.Create;

  ini := TIniFile.Create('settings.ini');
  try
    database.databasePassword := ini.ReadString('Database', 'password', '');
    database.databaseName := ini.ReadString('Database', 'name', '');
    vst.Enabled := ini.ReadBool('VST', 'enable', true);
  finally
    ini.Free;
  end;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  database.Free;
end;

end.
frmSettingsU:
Delphi-Quellcode:
unit frmSettingsU;

interface

uses
  IniFiles, ...;

type
  TfrmSettings = class(TForm)
    edtPassword: TEdit;
    edtDatabasName: TEdit;
    btnClose: TButton;
    chkvstEnable: TCheckBox;
    procedure btnCloseClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmSettings: TfrmSettings;

implementation

uses
  frmMainU;

{$R *.dfm}

procedure TfrmSettings.btnCloseClick(Sender: TObject);
begin
  Close;
end;

procedure TfrmSettings.FormCreate(Sender: TObject);
var
  ini: TInifile;
begin
  ini := TIniFile.Create('settings.ini');
  try
    edtPassword.Text := ini.ReadString('Database', 'password', '');
    edtDatabasName.Text := ini.ReadString('Database', 'name', '');
    chkvstEnable.Checked := ini.ReadBool('VST', 'enable', true);
  finally
    ini.Free;
  end;
end;

procedure TfrmSettings.FormDestroy(Sender: TObject);
var
  ini: TInifile;
begin
  database.databaseName := edtDatabasName.Text;
  database.databasePassword := edtPassword.Text;
  frmMain.vst.Enabled := chkvstEnable.Checked;

  ini := TIniFile.Create('settings.ini');
  try
    ini.WriteString('Database', 'password', edtPassword.Text);
    ini.WriteString('Database', 'name', edtDatabasName.Text);
    ini.WriteBool('VST', 'enable', chkvstEnable.Checked);
  finally
    ini.Free;
  end;
end;

end.
DatabaseU:
Delphi-Quellcode:
unit DatabaseU;

interface

type
  TMyDatabase = class(TObject)
  private
    FDatabaseName: string;
    FDatabasePassword: string;
  public
    property databaseName: string read FDatabaseName write FDatabaseName;
    property databasePassword: string read FDatabasePassword write FDatabasePassword;
  end;

implementation

end.
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Programmeinstellungen organisieren

  Alt 28. Okt 2014, 17:51
Sind doch sehr einfache Klassen? Wenn andere Klassen oder Formulare eine Instanz davon bekommen sollen dann kann man z.B. die über den constructor mitschicken. Bei Formularen würde ich allerdings empfehlen, dann das Formular nicht automatisch zu erstellen sondern in FormCreate des Hauptformulars.

Beispiel:

Delphi-Quellcode:
  TVstSettings = class
  private
    FEnabled: boolean;
  public
    property Enabled: boolean read FEnabled write FEnabled;
    procedure LoadFromFile(const FileName: string);
    procedure SaveToFile(const FileName: string);
    procedure Clear;
  end;

  TDatabaseSettings = class
  private
    FName: string;
    FPassword: string;
  public
    property Name: string read FName write FName;
    property Password: string read FPassword write FPassword;
    procedure LoadFromFile(const FileName: string);
    procedure SaveToFile(const FileName: string);
    procedure Clear;
  end;

  TSomeForm = class(TForm)
  private
    FDatabaseSettings: TDatabaseSettings;
  public
    constructor Create(AOwner: TComponent; Value: TDatabaseSettings); reintroduce; overload;
  end;

  TMainForm = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FDatabaseSettings: TDatabaseSettings;
  end;

constructor TSomeForm.Create(AOwner: TComponent; Value: TDatabaseSettings);
begin
  inherited Create(AOwner);
  FDatabaseSettings := Value; // Kopplung;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  FDatabaseSettings := TDatabaseSettings.Create;
  SomeForm := TSomeForm.Create(Self, FDatabaseSettings);
end;
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#10

AW: Programmeinstellungen organisieren

  Alt 29. Okt 2014, 10:35
@Bjoerk

danke so werde ich es jetzt erstmal machen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 07:11 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz