Hallo zusammen,
ich spiele gerad ein bischen mit dem Observer Muster rum und habe folgende Klassen erstellt:
Delphi-Quellcode:
IBeobachter = interface
['{965C77DA-CA00-4915-8133-2D865B8F8182}']
procedure Aktualisieren(iTemperatur, iFeuchtikgkeit, iDruck: real);
procedure Anzeigen;
end;
ISubject = interface
['{EB06F989-902A-43C1-8A58-DC671744DD2E}']
procedure RegistriereBeobachter(iIBeobachter: IBeobachter);
procedure EntferneBeobachter(iIBeobachter: IBeobachter);
procedure BenachrichtigeBeobachter;
end;
TWetterDaten = class(TInterfacedObject, ISubject)
private
Temperatur, Feuchtikgkeit, Druck : real;
FLstBeobachter : TInterfaceList; // !!!!!!!!!!!
public
constructor Create;
destructor Destroy; override;
procedure RegistriereBeobachter(iIBeobachter: IBeobachter);
procedure EntferneBeobachter(iIBeobachter: IBeobachter);
procedure BenachrichtigeBeobachter;
procedure MesswerteGeaendert;
procedure SetMesswerte(iTemperatur, iFeuchtikgkeit, iDruck : real);
end;
TTemperaturAnzeigen = class(TInterfacedObject, IBeobachter)
private
FWetterDaten : ISubject;
Temperatur, Feuchtikgkeit, Druck : real;
public
procedure Aktualisieren(iTemperatur, iFeuchtikgkeit, iDruck: real);
procedure Anzeigen;
constructor Create(iISubject : ISubject);
destructor Destroy; override; // Zum Testen !!!!
end;
TFeuchtigkeitAnzeigen = class(TInterfacedObject, IBeobachter)
private
FWetterDaten : ISubject;
Temperatur, Feuchtikgkeit, Druck : real;
public
procedure Aktualisieren(iTemperatur, iFeuchtikgkeit, iDruck: real);
procedure Anzeigen;
constructor Create(iISubject : ISubject);
end;
Ich habe mir ein Formular etstellt, in welchem ich die beiden Beobachter erstelle
Die beiden Beobachter erstelle in in meinem Formular bei Programmstart:
Delphi-Quellcode:
procedure TfrmMain.FormCreate(Sender: TObject);
begin
FWetterDaten := TWetterDaten.Create;
FWetterDaten.SetMesswerte(30,65,30);
FTemperaturAnzeigen := TTemperaturAnzeigen.Create(FWetterDaten);
FFeuchtigkeitAnzeigen := TFeuchtigkeitAnzeigen.Create(FWetterDaten);
end;
Über Buttons will ich die Beobachter "Ein/Aus Schalten"
Delphi-Quellcode:
procedure TfrmMain.Button2Click(Sender: TObject);
begin
FWetterDaten.RegistriereBeobachter(FTemperaturAnzeigen);
end;
procedure TfrmMain.Button3Click(Sender: TObject);
begin
FWetterDaten.RegistriereBeobachter(FFeuchtigkeitAnzeigen);
end;
procedure TfrmMain.Button4Click(Sender: TObject);
begin
FWetterDaten.EntferneBeobachter(FTemperaturAnzeigen);
end;
procedure TfrmMain.Button5Click(Sender: TObject);
begin
FWetterDaten.EntferneBeobachter(FFeuchtigkeitAnzeigen);
end;
procedure TfrmMain.Button6Click(Sender: TObject);
begin
FWetterDaten.BenachrichtigeBeobachter;
end;
Mein Problem ist aber, das nach dem Entfernen des Beobachters, diese Beobachter frei gegeben wird. Das sollte aber nicht sein.
Die Instanz des Beobachters habe ich doch in meinem Formular erstellt. Warum wird sie zerstört, nachdem ich sie aus der InterfaceList raus nehme?
Hier noch mein mein Subject und ein Beobachter:
Delphi-Quellcode:
{ TWetterDaten }
constructor TWetterDaten.Create;
begin
FLstBeobachter := TInterfaceList.Create;
end;
destructor TWetterDaten.Destroy;
begin
inherited;
end;
procedure TWetterDaten.BenachrichtigeBeobachter;
var
i : integer;
begin
for i := 0 to FLstBeobachter.Count - 1 do
IBeobachter(FLstBeobachter[i]).Aktualisieren(Temperatur, Feuchtikgkeit, Druck);
end;
procedure TWetterDaten.EntferneBeobachter(iIBeobachter: IBeobachter);
begin
FLstBeobachter.Remove(iIBeobachter);
end;
procedure TWetterDaten.RegistriereBeobachter(iIBeobachter: IBeobachter);
begin
FLstBeobachter.Add(iIBeobachter);
end;
procedure TWetterDaten.SetMesswerte(iTemperatur, iFeuchtikgkeit, iDruck: real);
begin
Temperatur := iTemperatur;
Feuchtikgkeit := iFeuchtikgkeit;
Druck := iDruck;
MesswerteGeaendert;
end;
procedure TWetterDaten.MesswerteGeaendert;
begin
BenachrichtigeBeobachter;
end;
Delphi-Quellcode:
procedure TTemperaturAnzeigen.Aktualisieren(iTemperatur, iFeuchtikgkeit, iDruck: real);
begin
Temperatur := iTemperatur;
Feuchtikgkeit := iFeuchtikgkeit;
Druck := iDruck;
Anzeigen;
end;
procedure TTemperaturAnzeigen.Anzeigen;
begin
ShowMessage('Aktuelle Wetterbedingungen: Temperatur:' + format('%f',[Temperatur]));
end;
constructor TTemperaturAnzeigen.Create(iISubject : ISubject);
begin
FWetterDaten := iISubject;
end;
destructor TTemperaturAnzeigen.Destroy;
begin
ShowMessage('Schade');
inherited;
end;