Hallo,
ich glaube maximov meint soetwas wie dies hier.
Delphi-Quellcode:
unit observer;
interface
uses SysUtils, classes;
Type
TNotifyArg =
class(TObject)
private
FMessageText:
String;
public
property MessageText :
String read FMessageText
write FMessageText;
end;
TObserverNotifycation =
procedure(Sender : TObject; MsgText :
String)
of object;
INotifyable =
interface
['
{6D8909ED-865B-4F92-A5E5-92195B5FB53D}']
procedure Notification(
const NotifyArg:TNotifyArg);
function GetNotify : TObserverNotifycation;
procedure SetNotify(
const Value : TObserverNotifycation);
property OnNotify : TObserverNotifycation
read GetNotify
write SetNotify;
end;
IObserveable =
interface
['
{D3EB90E2-4D09-4900-A61A-A5AB3D6E4E4B}']
procedure AddObserver(
const aObserver:INotifyable);
procedure RemoveObserver(
const aObserver:INotifyable);
end;
TObserver =
class(TInterfacedObject,INotifyable)
private
FOnNotify: TObserverNotifycation;
function GetNotify : TObserverNotifycation;
procedure SetNotify(
const Value : TObserverNotifycation);
public
procedure Notification(
const NotifyArg:TNotifyArg);
property OnNotify : TObserverNotifycation
read GetNotify
write SetNotify;
end;
TMessanger =
class(TInterfacedObject, IObserveable)
private
FList : IInterfaceList;
public
constructor Create;
destructor Destroy;
override;
procedure Notify;
procedure AddObserver(
const aObserver:INotifyable);
procedure RemoveObserver(
const aObserver:INotifyable);
end;
implementation
{ TObserver }
function TObserver.GetNotify: TObserverNotifycation;
begin
Result:=FOnNotify;
end;
procedure TObserver.SetNotify(
const Value: TObserverNotifycation);
begin
FOnNotify:=Value;
end;
procedure TObserver.Notification(
const NotifyArg: TNotifyArg);
begin
If Assigned(OnNotify)
then
FOnNotify(Self,NotifyArg.MessageText);
end;
{ TMessanger }
constructor TMessanger.Create;
begin
inherited Create;
FList:=TInterfaceList.Create;
end;
destructor TMessanger.Destroy;
begin
inherited Destroy;
end;
procedure TMessanger.AddObserver(
const aObserver: INotifyable);
begin
FList.Add(aObserver);
end;
procedure TMessanger.RemoveObserver(
const aObserver: INotifyable);
begin
FList.Remove(aObserver);
end;
procedure TMessanger.Notify;
var
iCnt : Integer;
NotifyArg : TNotifyArg;
begin
For iCnt := 0
to FList.Count-1
do
begin
NotifyArg:=TNotifyArg.Create;
Try
NotifyArg.MessageText:='
Notifycation_'+IntToStr(iCnt+1);
// as ruft hier implizit QueryInterface auf
(FList[iCnt]
as INotifyable).Notification(NotifyArg);
Finally
NotifyArg.Free;
end;
end;
end;
end.
TObserver implementiert das INotifyable Interface. Dadurch kann eine Instanz von TObserver den Methoden AddObserver und RemoveObserver von TMessanger übergeben werden.
Interessant ist an der Realisierung mit Interfaces, das man auch ein TEdit als Observer bei FMessanger anmelden kann.
TObserverEdit = class(TEdit,INotifyable)
siehe Beispiel.
Wenn ich die Sache richtig verstanden habe können alle Nachfahren von TComponent über Interfaces sehr einfach mit der Observerfähigkeit nachgerüstet werden. Eigene Klassen sollten Nachfahren von TInterfacedObject sein.
Kickt im Beispiel ein paar mal auf den Button "AddObserver" und einmal auf den Button "Create Edit and Add". Anschließend auf den Button "Notify"