AGB  ·  Datenschutz  ·  Impressum  







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

Interfaces - Multiple Inheritance

Offene Frage von "Stevie"
Ein Thema von ThE_-_BliZZarD · begonnen am 6. Aug 2010 · letzter Beitrag vom 8. Jun 2014
Antwort Antwort
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Interfaces - Multiple Inheritance

  Alt 7. Jun 2014, 16:00
Das ist ein guter Einwand.

Wenn man aber die Instanziierung der Klassen (Erzeugen der Objekte) auslagert und fortan nur noch mit Interfaces arbeiten will, dann braucht man wiederum mächtige Interfaces, die die gesamte Funktionalität veröffentlichen.
Andernfalls müsste man immer prüfen, ob das vorliegende (Objekt-)Interface nun gerade zufällig IRead oder IWrite unterstützt, darauf casten und dann auf die Propertys zugreifen.

Andererseits bringt das natürlich auch wieder Vorteile, da man so sehr flexibel mit den Objekt-Interfaces umgehen kann.
Eigentlich bräuchte man dann IReadWrite gar nicht sondern würde einfach mit IInterface arbeiten:

Delphi-Quellcode:
var RW: IInterface;
     X: Integer;
 ...
 RW := TFactory.GetNewRW; // erzeugt ein TReadWrite und gibt es als IInterface zurück
 ...
 if Supports(RW, IWrite) then
   (RW as IWrite).WriteInt(1);
 if Supports(RW, IRead) then
   X := (RW as IRead).ReadInt;
// bzw. auch über Property
 if Supports(RW, IWrite) then
   RW.Int := 1;
 if Supports(RW, IRead) then
   X := (RW as IRead).Int;

Dann braucht man sich gar nicht mehr kümmern, was genau da für ein Objekt vorliegt (eigentlich ja der Sinn von Interfaces).
Wenn man sicher ist, was man übergibt kann man Supports ja notfalls weg lassen.

Alternativ könnte man natürlich noch Variablen wie R: IRead und W: IWrite einführen.

Auf jeden Fall könnte man auf mächtige Schnittstellen als Klassenkopien so verzichten.

Aktuell scheint mir der Ansatz eigentlich sinnvoll zu sein (kann sich aber wieder ändern ).
Ginge das so?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Interfaces - Multiple Inheritance

  Alt 7. Jun 2014, 16:19
Wenn man sich an das SRP und das ISP hält, dann möchte man möglichst schlanke Interfaces. Und die Zusammenführung mehrerer Interfaces zu einem großen wäre wohl ein klarer Verstoß dessen.

Genau genommen ist schon allein das Supports abfragen des einen Interfaces auf das andere ein Code Smell, denn dadurch greift man von hinten rum auf etwas zu, was einem gar nicht übergeben wurde. Wenn ich möchte, dass nur lesender Zugriff erfolgt, übergeb ich das IRead Interface. Wenn sich nun jemand mit Supports mal ebend aus diesem Interface Schreibzugriff besorgt, ist das ziemlich bedenklich.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Interfaces - Multiple Inheritance

  Alt 7. Jun 2014, 16:45
Ok, die ersten 2 Sätze kann ich nachvollziehen.

Aber das Supports stinkt nicht so ganz.
Wenn ich einer Funktion bestimmte Objekt-Interfaces (also quasi irgendwelche Objekte) übergebe und dann diverse Dinge damit tun will, dann muss ich doch wissen, was ich vor mir habe.

Z.B. kann ich prüfen, ob ISerialization unterstützt wird und das Objekt dann serialisieren.
Wenn IOrganic unterstützt wird kann ich DoDestroying(1) aufrufen usw.

Dass Supports schlecht sein soll, erschließt sich mir irgendwie nicht.


NACHTRAG: Wenn ich absichtlich ein allgemeines Interface übergebe und damit ausdrücklich unterschiedliche Aktionen ermöglichen will, müsste mein Ansatz doch korrekt sein?
Ich sehe ein, dass der Ansatz fragwürdig wäre, wenn tatsächlich nur IRead übergeben wird und das Objekt aber dennoch auseinander genommen würde (ähnlich wie mit der RTTI).
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli ( 7. Jun 2014 um 16:48 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Interfaces - Multiple Inheritance

  Alt 7. Jun 2014, 22:07
Z.B. kann ich prüfen, ob ISerialization unterstützt wird und das Objekt dann serialisieren.
Wenn IOrganic unterstützt wird kann ich DoDestroying(1) aufrufen usw.

Dass Supports schlecht sein soll, erschließt sich mir irgendwie nicht.
In einem solchen Fall würdest du aber ein nicht referenzgezähltes Objekt übergeben und dort auf IWasAuchImmer überprüfen, um dann damit was zu machen und nicht ein bestimmtes Interface. Ich bezeichne solche Objekte mal als Datenobjekte. Sie könnten bestimmte Aspekte über Interfaces zur Verfügung stellen (wobei ich das auch nicht für das Gelbe vom Ei halte, dazu unten mehr).

Ich kann aber auch Interfaces als Services übergeben (im Gegensatz zu Datenobjekten sind das Klassen bzw Interfaces, die irgendwelche Arbeit erledigen) und da sollte man aufpassen, irgendwelche Annahmen darüber zu machen, welche Interfaces möglicherweise noch implementiert sind (Stichwort http://en.wikipedia.org/wiki/Leaky_abstraction). D.h. ich bekomm ein IFoo übergeben und versuche dann über Supports noch IBar zu bekommen um damit was zu machen. Erstens hab ich ein Problem, dass ich der API nicht ansehen kann dass man nicht nur IFoo braucht sondern möglicherweise auch noch IBar. Und zweitens haben ich somit eine implizite Abhängigkeit auf die Implementierung (wer stellt denn sicher, dass beide Interfaces von derselben Klasse implementiert werden).

Zu dem oben angesprochenen Punkt. Wenn Datenobjekte allerlei Interfaces implementieren, die dann irgendwas mit dem Objekt machen, handelt man sich sehr schnell Probleme mit dem SRP ein (das Objekt hält also nicht nur Daten, sondern Serialisiert sich, schreibt sich in die Datenbank, kann sich ausdrucken und vieles mehr). Zudem kommt es dann auch sehr schnell zu einer vermischung von verschiedenen Layern, die nix miteinander zu tun haben. Ich will damit nicht sagen, dass man das keineswegs machen sollte, aber man sollte aufpassen, welche Funktionalität man damit zur Verfügung stellt und inwieweit man seine Datenobjekte dann von anderen Schnittstellen abhängig macht.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie ( 7. Jun 2014 um 22:13 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.652 Beiträge
 
Delphi 12 Athens
 
#5

AW: Interfaces - Multiple Inheritance

  Alt 8. Jun 2014, 10:30
D.h. ich bekomm ein IFoo übergeben und versuche dann über Supports noch IBar zu bekommen um damit was zu machen. Erstens hab ich ein Problem, dass ich der API nicht ansehen kann dass man nicht nur IFoo braucht sondern möglicherweise auch noch IBar. Und zweitens haben ich somit eine implizite Abhängigkeit auf die Implementierung (wer stellt denn sicher, dass beide Interfaces von derselben Klasse implementiert werden).
Wobei das ja durch Supports nicht vorgeschrieben ist. Supports sagt ja nur, ob dieses Interface unterstützt wird und liefert gegebenenfalls einen Zeiger darauf zurück. Nirgendwo steht, daß dieses Interface von derselben Klasse implementiert sein muss wie das Ausgangs-Interface. Immerhin ist Supports die einzige Möglichkeit, sinnvoll mit einer polymorphen IInterfaceList zu arbeiten. Hinter jedem IInterface dieser Liste kann ein ganzer Schwanz von Klasseninstanzen stecken, die für die verschiedenen Interfaces zuständig sind, die man gerade abfragt, und wo die Instanzen bis zur Abfrage vielleicht noch gar nicht erzeugt sein müssen.

Mehr noch - bei passender Implementierung (Stichwort: TAggregatedObject und implements) muss die effektiv IFoo-implementierende Klasse ja gar nichts über IBar wissen. Es kommt doch am Ende nur darauf an, welches QueryInterface bei Supports aufgerufen wird.

Natürlich könnte man um von IFoo auf IBar zu kommen in IFoo auch eine Funktion einbauen, die das IBar zurückgibt, aber damit hat man wiederum eine Abhängigkeit von IFoo zu IBar geschaffen. Auch die Verlagerung in ein Über-Interface, das sowohl IFoo als auch IBar als Funktionen bereitstellt, ist m.E. nicht gerade erstrebenswert. Der Weg über Interface-Aggregation liefert im Endeffekt das gleiche, die Verwendung von Supports finde ich aber deutlich übersichtlicher. Ob ich dann nicht doch lieber beide Interfaces in einer Klasse implementiere kann dem aufrufenden Code dann aber egal sein.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Interfaces - Multiple Inheritance

  Alt 8. Jun 2014, 12:22
Es geht darum, dass es sich um eine implizite Annahme handelt, dass man wie auch immer von IFoo an ein IBar kommen kann, was ein Implementierungsdetail ist.

Wenn man sich mal durchliest, wo das ISP seinen Usprung hat dann dürfte einem schnell klar werden, wie gefährlich so Annahmen sein können, wenn es darum geht, entkoppelten Code zu schreiben. Wenn ich mir nämlich in meinem Code der eigtl nur ein IStapleJob Interface bekommt mit Supports mal ebend die Funktionalitäten von IPrintJob hole und damit was mache, dann ist das erstens nicht aus der API ersichtlich ("wieso funktioniert das nicht, ich hab doch ein IStapleJob reingegeben" oder auch "häh, wieso druckt der nun, ich wollt doch nur zusammenheften") und zweitens erschwere ich mir mal wieder das Testen. Ich kann nicht einfach ein IStapleJob Mock basteln und ihn hineingeben, nein ich muss auch noch dafür sorgen, dass mein Mock auch IPrintJob supportet.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie ( 8. Jun 2014 um 12:28 Uhr)
  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 00:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz