Hallo zusammen.
Ich habe für ein kleines Projekt das Observer-Pattern versucht möglichst wiederverwendbar und einfach umzusetzen. Ich würde gerne Eure Meinung und Verbesserungsvorschläge hören und gleichzeitig das Ganze auch alles hier zur Verfügung stellen.
Der Code des Patterns ist wie folgt:
Delphi-Quellcode:
unit PatObserver;
interface
uses SysUtils, Classes;
type
INotifyObserver =
interface
['
{F4A2A0D8-385E-4D38-ABF5-056ED79532BC}']
procedure ObserverNotify(Sender: TObject);
end;
TObserverSubject =
class
protected
ObserverCollection: TInterfaceList;
public
constructor Create;
destructor Destroy;
override;
procedure RegisterObserver(Observer: INotifyObserver);
procedure UnregisterObserver(Observer: INotifyObserver);
procedure NotifyObservers();
end;
implementation
{ TObserverSubject }
constructor TObserverSubject.Create;
begin
ObserverCollection := TInterfaceList.Create();
end;
destructor TObserverSubject.Destroy;
begin
FreeAndNil(ObserverCollection);
inherited;
end;
procedure TObserverSubject.RegisterObserver(Observer: INotifyObserver);
begin
ObserverCollection.Add(Observer);
end;
procedure TObserverSubject.UnregisterObserver(Observer: INotifyObserver);
begin
ObserverCollection.Remove(Observer);
end;
procedure TObserverSubject.NotifyObservers;
var
I: Integer;
fIntf: INotifyObserver;
begin
for I := 0
to ObserverCollection.Count - 1
do
begin
if Supports(ObserverCollection.Items[I], INotifyObserver, fIntf)
then
begin
fIntf.ObserverNotify(Self);
end;
end;
end;
end.
Ich habe das ganze eingesetzt, um bei Änderungen an einem Logbuch automatisch in allen möglichen Formularen automatisch benachrichtigt zu werden. Dazu habe ich im Logbuch folgendes ergänzt:
Delphi-Quellcode:
TLogFile = class(TInterfacedObject)
(*SNIP*)
public
Notifier: TObserverSubject;
constructor Create;
destructor Destroy; override;
(* SNIP *)
{...}
constructor TLogFile.Create;
begin
{...}
Notifier := TObserverSubject.Create;
end;
destructor TLogFile.Destroy;
begin
{...}
Notifier.Free;
inherited;
end;
An den Methoden, an denen das Logbuch verändert wird, wird dann
Notifier.NotifyObservers();
aufgerufen.
Um mich im LogViewer als Observer einzutragen habe ich folgendes gemacht:
Delphi-Quellcode:
{...}
type
TLogViewer = class(TForm, INotifyObserver)
{...}
private
procedure ObserverNotify(Sender: TObject);
{...}
procedure TLogViewer.FormCreate(Sender: TObject);
begin
inherited;
Logfile.Notifier.RegisterObserver(Self);
end;
procedure TLogViewer.FormDestroy(Sender: TObject);
begin
inherited;
Logfile.Notifier.UnregisterObserver(Self);
end;
procedure TLogViewer.ObserverNotify(Sender: TObject);
begin
// Hier auf die Benachrichtigung reagieren
end;