Wenn man das Logging elegant und flexibel machen möchte, dann braucht man zunächst eine
abstrakte Basisklasse oder ein
Interface.
Delphi-Quellcode:
unit MyLogger;
// eigene Unit
interface
type
TCustomLogger=class(TPersistent)
public
procedure LogMsg(level:integer;
const msg:
string);
virtual;
abstract;
end;
Davon werden nun eine oder mehrere konkrete Logging-Klassen abgeleitet:
Delphi-Quellcode:
TStringsLogger = class(TCustomLogger)
private
FList : TStrings;
public
constructor Create(list:TStrings);
// "level" dient dazu, verschieden Logmeldung (Fehler, Warnung, Info)
// voneinander zu trennen
procedure LogMsg(level:integer; const msg:string);override;
end;
implementation
constructor TStringsLogger.Create(list:TStrings);
begin
inherited Create;
FList := list;
end;
procedure TStringsLogger.LogMsg(level:integer; const msg:string);override;
begin
FList.Add(TimeToStr(Now)+' ('+IntToStr(level)+') '+msg;
end;
Im Hauptformular oder dort wo man die Log-Ausgabe sehen möchte erzeugt man ein Objekt der Klasse TStringsLogger:
Delphi-Quellcode:
procedure TFrmMain.FormCreate(Sender:TObject);
begin
// Logger-Objekt erzeugen und gleich an ein Memo-Feld anbinden
FLogger := TStringsLogger.Create(MemoLog.Lines);
end;
procedure TfrmMain.ConsoleLineOut(const Line: String);
begin
Flogger.LogMsg(0, Line);
end;
Der "Trick" ist nun, dass das Hauptformular das Logger-Objekt in das Unterformular einspeist.
Man nennt das
Dependency Injection.
Delphi-Quellcode:
procedure TFrmMain.ZeigeUnterformular;
begin
if not Assigned(FrmIrgendwas) then
FrmIrgendwas := TFrmIrgendwas.Create(Application);
FrmIrgendwas.Logger := FLogger; // Logger-Objekt weitergeben/einspeisen
FrmIrgendwas.Show;
end;
Das Unterformular sieht so aus:
Delphi-Quellcode:
uses MyLogger;
TFrmIrgendwas = Class(TForm)
...
public
// wird von aussen zugewiesen
Logger : TCustomLogger;
Procedure Test;
end;
Procedure TFrmIrgendwas.Test;
begin
Logger.LogMsg(99, 'Das ist eine Log-Meldung aus TFrmIrgendwas.Test');
end;
Sourcecode ohne Delphi-IDE eingehackt-kleine Schreibfehler bitte selber korrigieren
Das Hauptformular und das Unterformular arbeiten jetzt mit dem gleichen Logger-Objekt.
Meldungen vom Hauptformular und vom Unterformular laufen über das Logger-Objekt
in ein gemeinsames Memo-Feld.
Man könnte die Klasse TStringsLogger leicht durch eine andere Klasse z.B. TFileLogger austauschen
und die Log-Ausgabe in eine Datei schreiben.
Auch ein Kombination aus direkter Anzeige und Schreiben in eine Datei ist möglich.
Die Klassenstruktur die ich hier gezeigt habe ist flexibel und ohne zirkuläre Abhängigkeiten.
Mit einem Interface anstelle einer abstrakten Basisklasse ist noch mehr möglich,
aber das soll erst einmal reichen.