AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein dynamische Event "Liste" von Events?
Thema durchsuchen
Ansicht
Themen-Optionen

dynamische Event "Liste" von Events?

Ein Thema von Jonas Shinaniganz · begonnen am 3. Feb 2012 · letzter Beitrag vom 3. Feb 2012
Antwort Antwort
Benutzerbild von Jonas Shinaniganz
Jonas Shinaniganz

Registriert seit: 30. Aug 2011
249 Beiträge
 
Delphi XE5 Ultimate
 
#1

dynamische Event "Liste" von Events?

  Alt 3. Feb 2012, 11:17


In meiner Unit wird ein Event(A) aufgerufen welches einige weitere Methoden aufruft.

Auf dem Weg zu diesem Event(A) werden einige Enscheidungen getroffen und je nachdem sollen in dem Event(A) Methoden hinzugefügt oder gelöscht werden.

Das hinzufügen oder löschen soll zur Runtime erfolgen.

So inetwa könnte man mein Problem formulieren. Leider fehlt mir der Ansatz... als Stichwort habe Ich EventHandler gesucht aber bin nur auf für mich unverständliches gestoßen

Hat jemand einen Codeschnippsel mit dem Ich weitermachen kann?
  Mit Zitat antworten Zitat
neo4a

Registriert seit: 22. Jan 2007
Ort: Ingolstadt
362 Beiträge
 
Delphi XE2 Architect
 
#2

AW: dynamische Event "Liste" von Events?

  Alt 3. Feb 2012, 11:45
In meiner Unit wird ein Event(A) aufgerufen welches einige weitere Methoden aufruft.

Auf dem Weg zu diesem Event(A) werden einige Enscheidungen getroffen und je nachdem sollen in dem Event(A) Methoden hinzugefügt oder gelöscht werden.
Ist das Abarbeiten der Methodenliste in Event(A) statisch (d.h. Anzahl und Reihenfolge der Methodenaufrufe ist konstant), dann gnügt es m.E., dem Event ein Record als Parameter mitzugeben, dessen Members "unterwegs" gesetzt werden.

Im anderen Fall könnte es als Parameter eine Liste mit Methoden-Referenzen tun, die "unterwegs" gefüllt wird. Dann ist der Umfang und die Reihenfolge dynamisch und Event(A) muss noch nicht einmal die Methoden kennen.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Jonas Shinaniganz
Jonas Shinaniganz

Registriert seit: 30. Aug 2011
249 Beiträge
 
Delphi XE5 Ultimate
 
#3

AW: dynamische Event "Liste" von Events?

  Alt 3. Feb 2012, 12:40
Im anderen Fall könnte es als Parameter eine Liste mit Methoden-Referenzen tun, die "unterwegs" gefüllt wird. Dann ist der Umfang und die Reihenfolge dynamisch und Event(A) muss noch nicht einmal die Methoden kennen.
Das 2te hört sich super an.

Wie erstelle Ich eine Solche Liste, füge Referenzen hinzu, lösche die Referenzen und führe die Liste dann aus?

gruß
  Mit Zitat antworten Zitat
neo4a

Registriert seit: 22. Jan 2007
Ort: Ingolstadt
362 Beiträge
 
Delphi XE2 Architect
 
#4

AW: dynamische Event "Liste" von Events?

  Alt 3. Feb 2012, 13:28
Im anderen Fall könnte es als Parameter eine Liste mit Methoden-Referenzen tun, die "unterwegs" gefüllt wird. Dann ist der Umfang und die Reihenfolge dynamisch und Event(A) muss noch nicht einmal die Methoden kennen.
Das 2te hört sich super an.
Das habe ich befürchtet

Wie erstelle Ich eine Solche Liste, füge Referenzen hinzu, lösche die Referenzen und führe die Liste dann aus?
Das Problem bei diesem Ansatz ist es, dass Du keine Kontrolle über die Laufzeit der Methoden hast. Praktisch kann es bedeuten, dass zum Zeitpunkt der Ausführung, dass Callback-Objekt, das für die Ausführung verantwortlich sein soll, gar nicht mehr existiert -> AV.

Um auf der sicheren Seite zu sein, habe ich mich des Observer-Patterns bedient. Dazu registrieren sich die Objekte in einer zentralen Liste (Singleton) mit den Events, über die sie benachrichtigt werden wollen. Wichtig ist, dass sie sich auch wieder deregistrieren, bevor sie zerstört werden.

In Deinem Event(A) werden nun die Events getriggert, von der Observerliste entgegen genommen, die dann ihrerseits alle registrierten Observer benachrichtigt, die dann entsprechend in ihren Callback-Methoden weiter arbeiten können. Klingt vielleicht etwas aufwändiger als es letztlich ist.

So könnte die Observer-Komponente aussehen:
Delphi-Quellcode:
unit uObserver;
{ Zur Nutzung muss der Client:
  1. das Interface IdcObserver implementieren

  2. die Methode DoOnObserverNotification() bereitstellen und dort
    auf das passende Interface prüfen:
    if Supports(aInterface, IdcLangMan) then

  3. sich als Observer un/registrieren:
    Create: RegisterObserver(Self);
    Destroy: UnregisterObserver(Self);
 
  Die Notification erfolgt durch Aufruf von
  NotifyObserver() mit der Interface-Referenz
}

interface

uses
  Classes, SysUtils;
type
  IdcObserver = interface
    ['{5308A18A-FE7C-4A60-BB4F-34B2B9F8AAEF}']
    procedure DoOnObserverNotification(aInterface : IInterface; aParams : TObject = nil);
  end;

procedure RegisterObserver(aObject : TObject);
procedure UnregisterObserver(aObject : TObject);
procedure NotifyObserver(aInterface : IInterface; aParamObject : TObject = nil);

implementation

uses
  Generics.Collections;

  procedure RegisterObserver(aObject : TObject);
  procedure UnregisterObserver(aObject : TObject);
  procedure NotifyObserver(aInterface : IInterface; aParamObject : TObject = nil);

{
  Die Items sind Referenzen auf die Komponenten, die IdcObserver implementieren.
  Items werden benachrichtigt und müssen selbst richtig darauf reagieren (s.o.).
}

  TdcObserList = TList<IdcObserver>;

  TdcObserverList = class(TInterfacedObject)
  private
    FObserverList : TdcObserList;
    procedure RegisterObserver(aObserver : IdcObserver);
    procedure UnregisterObserver(aObserver : IdcObserver);
    procedure NotifyObserver(aInterface : IInterface; aParamObject : TObject = nil);
  public
    constructor Create;
    destructor Destroy; override;
  end;

var
  aObserList : TdcObserverList;

procedure RegisterObserver(aObject : TObject);
var
  aObserver : IdcObserver;
begin
  if Supports(aObject, IdcObserver, aObserver) then
    aObserList.RegisterObserver(aObserver);
end;

procedure UnregisterObserver(aObject : TObject);
var
  aObserver : IdcObserver;
begin
  if Supports(aObject, IdcObserver, aObserver) then
    aObserList.UnregisterObserver(aObserver);
end;

procedure NotifyObserver(aInterface : IInterface; aParamObject : TObject = nil);
begin
  aObserList.NotifyObserver(aInterface, aParamObject);
end;

{ TdcObserverList }

constructor TdcObserverList.Create;
begin
  FObserverList := TdcObserList.Create;
end;

destructor TdcObserverList.Destroy;
begin
  FObserverList.Free;
  inherited;
end;

procedure TdcObserverList.NotifyObserver(aInterface : IInterface; aParamObject : TObject = nil);
var
  aObserver : IdcObserver;
begin
  for aObserver in FObserverList do
    aObserver.DoOnObserverNotification(aInterface, aParamObject);
end;

procedure TdcObserverList.RegisterObserver(aObserver: IdcObserver);
begin
  FObserverList.Add(aObserver);
end;

procedure TdcObserverList.UnregisterObserver(aObserver: IdcObserver);
begin
  FObserverList.Remove(aObserver);
end;

initialization
  aObserList := TdcObserverList.Create;

finalization
  FreeAndNil(aObserList);

end.
Ich habe das Sample aus einem Projekt von mir entnommen, wo der Observer selbst mittels Spring-DI verwaltet wird, was ich zur besseren Übersichtlichkeit entfernt habe. Insoweit können ggf. noch Anpassungen erforderlich sein. Aber vielleicht hilft es auch so.
Andreas

Geändert von neo4a ( 3. Feb 2012 um 14:11 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Jonas Shinaniganz
Jonas Shinaniganz

Registriert seit: 30. Aug 2011
249 Beiträge
 
Delphi XE5 Ultimate
 
#5

AW: dynamische Event "Liste" von Events?

  Alt 3. Feb 2012, 14:25
Okay das ist schon wirklich ein Hammer und kann warscheinlich um EINGIES mehr als nötig.

Gibt mir dafür mal bis morgen
  Mit Zitat antworten Zitat
Antwort Antwort


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 05:58 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