AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Observer-Pattern Implementation
Thema durchsuchen
Ansicht
Themen-Optionen

Observer-Pattern Implementation

Ein Thema von Ghostwalker · begonnen am 10. Nov 2016 · letzter Beitrag vom 11. Nov 2016
Antwort Antwort
Der schöne Günther

Registriert seit: 6. Mär 2013
6.114 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

AW: Observer-Pattern Implementation

  Alt 10. Nov 2016, 16:29
ich weiß noch nichtmal was das ist.
Das nennt sich Anonyme Methode.
Was "Turbo Pascal" ist, meinte ich


Java hat so etwas ja erst extrem spät bekommen, viele Observer-Pattern Implementationen in Delphi sehen so aus als hätte man sie aus Java 1:1 übernommen



Warum soll sich ein Objekt bei einem anderen mehrmals für die gleiche Notification registrieren ?????
Unverhofft kommt oft
Ich meinte aber eher: Wenn sich ein Objekt bei zwei Observables vom gleichen Typ registrieren will - Dann rufen beide zwangsläufig die gleiche Methode auf, obwohl man das sicher nicht will.
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Observer-Pattern Implementation

  Alt 10. Nov 2016, 16:42
Unverhofft kommt oft
Ich meinte aber eher: Wenn sich ein Objekt bei zwei Observables vom gleichen Typ registrieren will - Dann rufen beide zwangsläufig die gleiche Methode auf, obwohl man das sicher nicht will.

Doch, genau das will ich, zumindest in dem geplanten Anwendungsfall. Der Unterschied besteht hier lediglich in den übergebenen Daten bei der Notification (daher auch Pointer !)
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Observer-Pattern Implementation

  Alt 10. Nov 2016, 18:48
So dale, noch mal ein Update.

Hab das ganze nochmal komplet umgebaut. Source im Anhang.

Achtung hab da FastMM4 eingebunden, um zu checken ob Memory-Leaks entstehen

Generics wären schön, insbesondere bei der Methodlist bzw. deren Nachfahren. Habsch aber net.

Jetzt ist wieder euer Meinung gefragt
Angehängte Dateien
Dateityp: zip Observertest.zip (4,0 KB, 11x aufgerufen)
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Devstructor

Registriert seit: 7. Sep 2016
4 Beiträge
 
FreePascal / Lazarus
 
#4

AW: Observer-Pattern Implementation

  Alt 11. Nov 2016, 07:11
Hi,

ich hatte mal für ein privates Projekt Observer-Komponenten geschrieben. Du kannst da mal rüber schauen
Mit einer List hatte ich nicht gearbeitet, sondern mit einer TInterfacedList, das wäre sicher eine Optimierung
Der TMBObserver ist eigentlich nur eine Basiskomponente, man könnte auch einfach das Interface IMBObserver zum Beispiel einem Form hinzufügen.

Delphi-Quellcode:
unit MBSubject;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, MBObserver;

type
  IMBSubject = interface
    ['{A89B6DD9-711C-4444-BF29-1AB0335A489C}']
    procedure AddObserver(Observer: IMBObserver);
    procedure RemoveObserver(Observer: IMBObserver);
    procedure ClearObservers;
    procedure NotifiyObservers;
  end;

  { TMBSubject }

  TMBSubject = class(TComponent, IMBSubject)
  private
    FEnabled: Boolean;
    FObservers: TInterfaceList;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure AddObserver(Observer: IMBObserver);
    procedure RemoveObserver(Observer: IMBObserver);
    procedure ClearObservers;

    procedure NotifiyObservers;
  published
    property Enabled: Boolean read FEnabled write FEnabled default True;
  end;

procedure Register;

implementation

procedure Register;
begin
  {$I mbsubject_icon.lrs}
  RegisterComponents('MBComponents',[TMBSubject]);
end;

{ TMBSubject }

constructor TMBSubject.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FObservers:=TInterfaceList.Create;
  FEnabled:=True;
end;

destructor TMBSubject.Destroy;
begin
  if Assigned(FObservers) then FreeAndNil(FObservers);

  inherited Destroy;
end;

procedure TMBSubject.AddObserver(Observer: IMBObserver);
begin
  if FObservers.IndexOf(Observer) = -1 then FObservers.Add(Observer);
end;

procedure TMBSubject.RemoveObserver(Observer: IMBObserver);
begin
  FObservers.Remove(Observer);
end;

procedure TMBSubject.ClearObservers;
begin
  FObservers.Clear;
end;

procedure TMBSubject.NotifiyObservers;
var
  i: Integer;
  Observer: IMBObserver;
begin
  if not FEnabled then Exit;

  for i := 0 to Pred(FObservers.Count) do
    if Supports(FObservers.Items[i], IMBObserver, Observer) then Observer.SubjectChanged(Self);
end;

end.
Delphi-Quellcode:
unit MBObserver;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources;

type
  IMBObserver = interface
    ['{512FD47A-6122-4EFF-9ED4-09AC795EF794}']
    procedure SubjectChanged(Sender: TObject);
  end;

  { TMBObserver }

  TMBObserver = class(TComponent, IMBObserver)
  private
    FOnSubjectChanged: TNotifyEvent;
  protected
    procedure SubjectChanged(Sender: TObject);
  published
    property OnSubjectChanged: TNotifyEvent read FOnSubjectChanged write FOnSubjectChanged;
  end;

procedure Register;

implementation

procedure Register;
begin
  {$I mbobserver_icon.lrs}
  RegisterComponents('MBComponents',[TMBObserver]);
end;

{ TMBObserver }

procedure TMBObserver.SubjectChanged(Sender: TObject);
begin
  if Assigned(FOnSubjectChanged) then FOnSubjectChanged(Sender);
end;

end.
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Observer-Pattern Implementation

  Alt 11. Nov 2016, 08:41
Erstmal Danke für deine Anmerkungen

Da ich keine Interfaces speichere und auch ganz gern auf das automatische Instanzhandling verzichten möchte, hab ich mich ganz bewußt gegen TInterfaceList entschieden.

Stattdessen speichere ich nur noch Methodenzeiger in folgender Liste bzw einer davon abgeleiteten Klasse:

Delphi-Quellcode:
TYPE
  PMethod = ^TMethod;
  TMethodList = Class(TObject)
    PRIVATE
       flist : TList;
       function getMethod(Index: integer): TMethod;
       procedure setMethod(Index: integer; const Value: TMethod);
    PROTECTED
       function getCount:integer;
       function indexOf(proc:TMethod):integer;
    PUBLIC
       Constructor Create;
       Destructor Destroy;override;

       Procedure Clear;
       procedure Add(const proc:TMethod);
       procedure Remove(const proc:TMethod);
       property Items[Index:integer]:TMethod read getMethod write setMethod;
    PUBLISHED
       Property Count:integer read getCount;
  End;
Damit laufe ich nicht Gefahr, das mir die Liste plötzlich mein Objekt unterm Allerwertesten wegzieht
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.617 Beiträge
 
#6

AW: Observer-Pattern Implementation

  Alt 11. Nov 2016, 09:25
Als kleiner Tipp: Es gibt sehr gute Implementierungen der ganzen Sache (also Obersever Pattern und Iterator Pattern) mit einem größtenteils sehr einheitlichen Interface: http://reactivex.io/

Leider ist hier (noch? ) keine Bibliothek für Delphi dabei.

Aber auch wenn ich es jetzt gerade nicht geschafft habe Dich zu überreden diese zu erstellen *g*, so empfehle ich auf jeden Fall, dass Du Dir dort mal anguckst, wie das in anderen Sprachen realisiert wurde. Rx hat sehr viele Anhänger, und aus meiner Sicht nicht umsonst. Damit zu arbeiten empfinde ich (zumindest in C# und JavaScript) als sehr angenehm.

Von daher lohnt es sich auf jeden Fall mal, sich das mal intensiver anzuschauen und sich ggf. von dort inspirieren zu lassen, bevor man sonst eine eigene Lösung ohne diesen Input baut, die dann sonst möglicherweise Schwächen hat die Rx schon an anderen Stellen ausgemerzt hat.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.012 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#7

AW: Observer-Pattern Implementation

  Alt 11. Nov 2016, 11:09
Als kleiner Tipp: Es gibt sehr gute Implementierungen der ganzen Sache (also Obersever Pattern und Iterator Pattern) mit einem größtenteils sehr einheitlichen Interface: http://reactivex.io/

Leider ist hier (noch? ) keine Bibliothek für Delphi dabei.
Ich hab kürzlich angefangen, das in Spring4D zu implementieren, allerdings hat das noch internen Prototyp Status
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  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 21:08 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