Thema: Delphi Observer:

Einzelnen Beitrag anzeigen

GroHae

Registriert seit: 19. Apr 2007
Ort: Nabburg
83 Beiträge
 
Delphi 2007 Enterprise
 
#1

Observer:

  Alt 21. Jul 2010, 09:42
Delphi-Version: 2007
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;
Grüße

Thomas
  Mit Zitat antworten Zitat