AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Interfaces Generics

Ein Thema von Jonas Shinaniganz · begonnen am 8. Nov 2012 · letzter Beitrag vom 9. Nov 2012
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Jonas Shinaniganz
Jonas Shinaniganz

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

Interfaces Generics

  Alt 8. Nov 2012, 15:18
Eine kurze Frage zum Thema.

Wie muss Ich meinen Code ändern damit der "Publisher" Elemente, welche das Interface "ISubscriber" implementieren, aufnimmt?


Delphi-Quellcode:
  ISubscriber = interface
    procedure GetNewspaper(Newspaper : TNewspaper);
  end;

  // Die generische Liste soll Elemente, welche das Interface implementieren, verwalten
  TPublisher = class(TObjectList<ISubscriber>)
  public
    procedure AddSubscriber(ISubscriber);
    procedure RemoveSubscriber(ISubscriber);
    procedure MessageAllSubscriber;
  end;
Ich kann die Generische Klasse aber nur mit einem konkreten Klassen-Parameter vererben oder instanzieren.

Ich will aber das da oben Wieso sollte meiner generischen Liste nicht das Interface genügen? Das wäre echte Kapselung.

Was kann ich machen?
Die Leiter der Entwicklungsabteilung dreht total am Mausrad!
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#2

AW: Interfaces Generics

  Alt 8. Nov 2012, 15:35
Eine kurze Frage zum Thema.
Wie muss Ich meinen Code ändern damit der "Publisher" Elemente, welche das Interface "ISubscriber" implementieren, aufnimmt?

Delphi-Quellcode:
type
 ISubscriber = interface
    procedure GetNewspaper(Newspaper : TObject);
  end;

  // Die generische Liste soll Elemente, welche das Interface implementieren, verwalten
  TPublisher = class(TList<ISubscriber>)
  public
    procedure AddSubscriber(S: ISubscriber);
    procedure RemoveSubscriber(S: ISubscriber);
    procedure MessageAllSubscriber;
  end;

Erklärung: TList kann Schnittstellen, TObjectList nicht.

Stilistisch würde ich aber keine AddSubscriber / RemoveSubscriber Methoden deklarieren, denn wenn diese eigenen Code enthalten der in der Oberklasse Add/Remove Methode nicht enthalten ist, könnten Klienten der Klasse weiter auf Add/Remove zugreifen (absichtlich oder unabsichtlich) und damit den eigenen Code umgehen.
Michael Justin
habarisoft.com

Geändert von mjustin ( 8. Nov 2012 um 15:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Jonas Shinaniganz
Jonas Shinaniganz

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

AW: Interfaces Generics

  Alt 8. Nov 2012, 15:40
Liegt das einfach daran, das Add und Sub aus IMath und _AddRef, _Release und QueryInterface aus IInterface dort nicht implementiert sind?

Ich wollte doch auchnoch das Typecasting umgehen. Ach Ich sehe grade, du verwendest auch die generische TList. Okay gut.

Und wenn Ich jetzt noch sowas wie OwnsObjects haben möchte? Selbst schreiben?
Die Leiter der Entwicklungsabteilung dreht total am Mausrad!
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#4

AW: Interfaces Generics

  Alt 8. Nov 2012, 15:42
OwnsObjects bei interfaces ?
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Jonas Shinaniganz
Jonas Shinaniganz

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

AW: Interfaces Generics

  Alt 8. Nov 2012, 15:44
Ja "OwnsObjects bei interfaces" . Das wäre nett.

Aber ich merke schon an der Art deines Posts, da will ich scheinbar zu viel / etwas was nicht möglich ist. Auf das ich mit nachdenken wohl auch selbst kommen sollte.

Die Leiter der Entwicklungsabteilung dreht total am Mausrad!
  Mit Zitat antworten Zitat
Benutzerbild von Jonas Shinaniganz
Jonas Shinaniganz

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

AW: Interfaces Generics

  Alt 8. Nov 2012, 15:52
Zitat:
Stilistisch würde ich aber keine AddSubscriber / RemoveSubscriber Methoden deklarieren, denn wenn diese eigenen Code enthalten der in der Oberklasse Add/Remove Methode nicht enthalten ist, könnten Klienten der Klasse weiter auf Add/Remove zugreifen (absichtlich oder unabsichtlich) und damit den eigenen Code umgehen.
Ich wollte eigentlich nur bessere Namen für die Add / Remove Methoden erzielen. Vielleicht sollte Ich die TObjectList besser als Feld meiner TPublisher Klasse deklarieren, ich denke, dann trifft es eher die Art, wie ich sie mir in meinem Konzept ausgedacht habe.

Delphi-Quellcode:
TPublisher
private
  Subscribers : TList;
public
  procedure AddSubscriber(Subscriber : ISubscriber);
  procedure RemoveSubscriber(Subscriber : ISubscriber);
In dem oberen Beispiel kann Ich ja auch noch die generische Version der TList nehmen.
Die Leiter der Entwicklungsabteilung dreht total am Mausrad!
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Interfaces Generics

  Alt 8. Nov 2012, 16:39
Wenn du im zuletzt geposteten Beispiel die Subscriber in einer TList speicherst, haust du dir u.U. den RefCount kaputt. Denn das AddSubscriber sorgt nur für eine weak Reference auf deinen Subscriber (es wird beim adden in die TList, welche ja nur Pointer aufnimmt, kein _AddRef durchgeführt). Wenn dieser Subscriber somit irgendwo out of scope läuft und (sofern du natürlich das automatische Refcounting von TInterfacedObject z.B. benutzt) freigegeben wird, hängt in deiner Subscriber Liste ein dangling Pointer und beim nächsten Zugriff darauf (z.B. durch MessageAllSubscribers) knallts.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von Jonas Shinaniganz
Jonas Shinaniganz

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

AW: Interfaces Generics

  Alt 8. Nov 2012, 16:47
Okay ich habe scheinbar die IInterfaces noch nicht ganz verstanden.

Hier ist mein Konzept:

Delphi-Quellcode:

type
  TNewspaper = class
  private
    FTitle : String;
    procedure SetTitle(const Value : String);
  public
    property Title : String read FTitle write SetTitle;
  end;

  ISubscriber = interface
    procedure GetNewspaper(Newspaper : TNewspaper);
  end;

  TPublisher = class
  protected
    Subscribers : TList<ISubscriber>;
  public
    constructor Create;
    procedure AddSubscriber(Subscriber : ISubscriber); virtual; abstract;
    procedure RemoveSubscriber(Subscriber : ISubscriber); virtual; abstract;
    procedure SendNewsToAllSubs; virtual; abstract;
  end;
Hier sind ein paar konkrete Klassen:

Delphi-Quellcode:

type

  TFAZ = class(TPublisher)
  private
    FCurrentNewspaper : TNewspaper;
    procedure SetCurrentNewspaper(const Value: TNewspaper);
    function GetCurrentNewspaper : TNewspaper;
  public
    procedure AddSubscriber(Subscriber : ISubscriber); override;
    procedure RemoveSubscriber(Subscriber : ISubscriber); override;
    procedure SendNewspaperToAllSubs;
    property CurrentNewspaper : TNewspaper read GetCurrentNewspaper write SetCurrentNewspaper;
  end;

  TFischer = class(TInterfacedObject, ISubscriber)
    procedure GetNewspaper(Newspaper : TNewspaper);
  end;

  TMeier = class(TInterfacedObject, ISubscriber)
    procedure GetNewspaper(Newspaper : TNewspaper);
  end;

Zitat:
Wenn du im zuletzt geposteten Beispiel die Subscriber in einer TList speicherst, haust du dir u.U. den RefCount kaputt. Denn das AddSubscriber sorgt nur für eine weak Reference auf deinen Subscriber (es wird beim adden in die TList, welche ja nur Pointer aufnimmt, kein _AddRef durchgeführt). Wenn dieser Subscriber somit irgendwo out of scope läuft und (sofern du natürlich das automatische Refcounting von TInterfacedObject z.B. benutzt) freigegeben wird, hängt in deiner Subscriber Liste ein dangling Pointer und beim nächsten Zugriff darauf (z.B. durch MessageAllSubscribers) knallts.

Wie verwalte ich denn dann korrekter Weise meine Referenzen? Gibt es die Möglichkeit mir den Referenzzähler der Interface-Klasse zunutzen zu machen? Ist sowas sogar so gedacht? Wie würde ich das denn machen?

Grüße
Die Leiter der Entwicklungsabteilung dreht total am Mausrad!
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#9

AW: Interfaces Generics

  Alt 8. Nov 2012, 17:11
es wird beim adden in TList, welche nur Pointer aufnimmt, kein _AddRef durchgeführt
Gilt das obige denn auch für die generische TList<Interface>?
Michael Justin
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Interfaces Generics

  Alt 8. Nov 2012, 17:16
es wird beim adden in TList, welche nur Pointer aufnimmt, kein _AddRef durchgeführt
Gilt das obige denn auch für die generische TList<Interface>?
Nein, der Compiler sorgt dafür, dass für managed Typen der richtige Source generiert wird (im Falle von Interfaces _AddRef und _Release, bzw IntfCopy).
Daher ist auch eine TList<TFoo> und TList<IFoo> binär inkompatibel, weil für Objekte und Interfaces unterschiedlicher Code generiert wird, obwohl es naiv gesagt beides nur Listen sind, die nen Pointer speichern.


Zitat:
Wenn du im zuletzt geposteten Beispiel die Subscriber in einer TList speicherst, haust du dir u.U. den RefCount kaputt. Denn das AddSubscriber sorgt nur für eine weak Reference auf deinen Subscriber (es wird beim adden in die TList, welche ja nur Pointer aufnimmt, kein _AddRef durchgeführt). Wenn dieser Subscriber somit irgendwo out of scope läuft und (sofern du natürlich das automatische Refcounting von TInterfacedObject z.B. benutzt) freigegeben wird, hängt in deiner Subscriber Liste ein dangling Pointer und beim nächsten Zugriff darauf (z.B. durch MessageAllSubscribers) knallts.

Wie verwalte ich denn dann korrekter Weise meine Referenzen? Gibt es die Möglichkeit mir den Referenzzähler der Interface-Klasse zunutzen zu machen? Ist sowas sogar so gedacht? Wie würde ich das denn machen?

Grüße
Ob du Referenzzählung nutzt oder nicht, hängt wohl von deinem Design ab. Es gibt pro und contra. Das würde aber den Rahmen dieses Thread sprengen, darüber zu philosophieren

Konkret zum Thema hier: Benutz zum Speichern deiner Subscriber TList<ISubscriber>. Ob die Klassen, welche ISubcriber implementieren, Refcounting haben oder nicht, ist dann erstmal irrelevant.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie ( 8. Nov 2012 um 17:27 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 08:03 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