Interfaces in Delphi
spacer
Autor Nachricht
theo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 62

Win 2000, XP, Vista; Win 7
Delphi 6, 7, 2010, MSSQL, Firebird, DevExpress
BeitragVerfasst: Mo 07.11.11 22:27 
Hallo,

ich möchte die Meinungen von anderen Programmiern zu folgenden Thema hören:

Was spricht für oder gegen den Ansatz:
- ALLE! Objekte über ein interface abzubilden und den Zugriff nur über interface zuerstellen -
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.


Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Mo 07.11.11 22:57 
Wenn die Performance keine Rolle spielt, mag man daran denken. Aber eine der Vorteile von Delphi ist gerade, dass es keinen integrierten Garbage Collector hat. Wenn man alle Objekte über Interfaces ansprechen würde, würde man sich die entsprechenden Nachteile mit aufhalsen.

Ich sehe aber weder einen Sinn, noch echte Vorteile darin, also warum sollte man das wollen? :gruebel:

Mit Interfaces kann man die rein baumartige Vererbung in Delphi erweitern. Und dafür sind Interfaces auch gut. Auch für einige andere Zwecke sind sie sinnvoll. Aber für alle Objekte?
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic starofftopic star
Beiträge: 617
Erhaltene Danke: 9

Windows XP/7 Kubuntu
RAD XE2
BeitragVerfasst: Mo 07.11.11 23:19 
also ALLE Objekte über EIN interface? ;-)

Der Vorteil von Interfaces liegt klar im Design der Anwendung. Wenn man das Fachmodell über Interfaces aufbaut kann man dieses sehr einfach über Unit-Tests überprüfen (Stichwort MOCK), ein ggf. tief geschachteltes Vererbungsmonster kann abgeflacht werden und Abhängigkeiten zwischen Klassen werden aufgebrochen (Stichwort programmieren gegen Schnittstellen und nicht gegen eine Implementierung).

Aber klar bringt das auch Nachteile mit sich. In der letzten Ekon (vor 2 Wochen) gab es dazu einen KLasse Workshop von Bern Ua und Daniel Wischnewski. Da meinte Bernd Ua sinngemäß: eine gut zu testende Anwendung hat ne schlechte Performance.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
theo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 62

Win 2000, XP, Vista; Win 7
Delphi 6, 7, 2010, MSSQL, Firebird, DevExpress
BeitragVerfasst: Di 08.11.11 00:46 
Pro Objekt ein Interface
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 452
Erhaltene Danke: 10

Win XP, Debian GNU/Linux
Delphi 2007 Enterprise, Java, C#
BeitragVerfasst: Di 08.11.11 12:12 
user profile icontheo hat folgendes geschrieben Zum zitierten Posting springen:
Pro Objekt ein Interface

Warum :?:
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
theo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 62

Win 2000, XP, Vista; Win 7
Delphi 6, 7, 2010, MSSQL, Firebird, DevExpress
BeitragVerfasst: Di 08.11.11 20:04 
user profile iconbaka0815 hat folgendes geschrieben Zum zitierten Posting springen:
user profile icontheo hat folgendes geschrieben Zum zitierten Posting springen:
Pro Objekt ein Interface

Warum :?:

Dieses "Warum" ist genau meine Frage, weil wir im Team einen Kollegen haben, der fast Alles über INTERFACES macht.

Ich persönlich bin der Meinung, dass ein wohl überlegtes Klassenmodell mehr den allgemeinem Programmierstill in Delphi entspricht. Wobei INTERFACES natürlich auch eine Berechtigung haben (z.B. XML-Datenanbindung, COM-Schnittstelle).
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Di 08.11.11 20:56 
user profile icontheo hat folgendes geschrieben Zum zitierten Posting springen:
Dieses "Warum" ist genau meine Frage, weil wir im Team einen Kollegen haben, der fast Alles über INTERFACES macht.
Wie es in dem Fall ist, kann man von außen natürlich schlecht sagen, aber positive Gründe fallen mir beim besten Willen nicht ein.

Jetzt mal abgesehen von COM oder ähnlichem, wo man nicht um Interfaces herumkommt, können Interfaces rein in Delphicode helfen, wenn man es nicht hinbekommt eine saubere Klassenkapselung zu erstellen, bei denen die Beziehungen zwischen den Klassen nur in eine Richtung gehen. Ohne Interfaces ließe sich so etwas nur durch Kreuzbezüge lösen, was aber nicht immer hinzubekommen ist, wenn man sich da zu sehr festgefahren hat. In manchen Fällen machen Interfaces dann aber durchaus Sinn.

Zudem hilft es, wenn man keine saubere Struktur hinbekommt, bei der man an definierten Stellen die Objekte auch wieder freigibt. Denn durch die Interfaces erledigt das der automatisch generierte Code des Compilers automatisch.

Aber hast du denn nicht mal gefragt was der Hintergrund ist? Ich meine er muss es doch (hoffentlich) am besten wissen warum er das so macht.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 452
Erhaltene Danke: 10

Win XP, Debian GNU/Linux
Delphi 2007 Enterprise, Java, C#
BeitragVerfasst: Mi 09.11.11 10:02 
Interfaces machen nur dann Sinn, wenn man mehrere Objekte hat, die dasselbe Ziel verfolgen.

Wenn man z.B. das Laden einer Datei generalisieren möchte:
Man bekommt z.B. ein Objekt vom Typ IFile von der FileLoadFactory zurück, welches dann ein TWord, TExcel, TText, TWhatever ist.

Wenn man ein Listener-Konzept (siehe Java) umsetzen möchte:
Das Listener-Interface liefert nur die aufzurufende Methode, die Implementierung bleibt dann wem anders überlassen.

Warum man jedoch für JEDES Objekt auch ein Interface haben möchte, ist für mich so nicht ersichtlich.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Beiträge: 2682
Erhaltene Danke: 26



BeitragVerfasst: Sa 12.11.11 01:55 
In .NET/Java macht man das manchmal, um die Klassen isoliert voneinander testen zu können. Allerdings setzt das einen DI-Mechanismus voraus. DI ohne GC ist schwer zu realisieren und verkompliziert das ganze wahrscheinlich nur.

Interfaces sind in Delphi schlecht umgesetzt. Das ganze ist zu stark an COM angelehnt. Ich denke mal dafür wurde es ursprünglich entwickelt. Das ganze hat einfach noch viele Kanten und Ecken. Es gibt keine volle Unterstützung von Properties; kein voller Language-Support mit "is" und "as" sondern über "Supports"; man muss für gewisse Features Guids angeben; man muss einen anderen Programmierstil verwenden wegen der Referenzzählung; man kann trotz Referenzzählung Memory-Leaks erzeugen (Interface-Instanz weist sich einem Childobjekt zu oder zirkuläre Abhängigkeit) dagegen gibt es kein Gegenmittel wie Weak References ausser man manipuliert die Referenzzählung; früher konnte man Interfaces nicht mehr zu Objekte casten.

Für viele dieser Dinge gibt es technische Erklärungen, aber .NET hat all diese Problemchen und Einschränkungen einfach nicht...

Fazit: In Delphi ist es unüblich und ich würde davon abraten.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Di 29.11.11 20:30 
Mittlerweile habe ich auch herausgefunden, dass z.B. Nick Hodges ein Anhänger dieser Verfahrensweise ist. Hauptzweck: Die einzelnen Codeteile voneinander entkoppeln. Mehr dazu hier im Video:
www.embarcadero.com/coderage/sessions
(Mittwoch: Delphi, Dependency Injection, and the Delphi Spring Framework)

Kurzfassung meiner Meinung dazu:
Die Idee dahinter ist durchaus nachvollziehbar und an sich nicht schlecht, aber ich halte das so nicht für sauberen Code. Mit irgendwelchen Generatorklassen herumwerfen, die Klassen erzeugen ohne dass man direkt sieht wo die Implementierung herkommt? Aus Versehen die falsche Unit entfernt oder hinzugefügt und plötzlich geht etwas nicht mehr, weil es keine Fehlermeldung gibt? (Weil der Compiler das nicht prüfen kann.)

Sorry, aber das ist meiner Meinung nach einfach nicht richtig durchdacht, birgt Gefahren insbesondere bei der Arbeit im Team und ist daher keine saubere Softwarearchitektur.

Die Verwendung von Interfaces um gezielt Codeteile zu entkoppeln macht an den richtigen Stellen durchaus Sinn, aber in der Form nicht. So überwiegen die Nachteile und es besteht die Gefahr, dass jemand durch Änderungen Probleme an ganz anderer Stelle verursacht und es durch das Konzept gar nicht mitbekommen kann. Eben weil man die Compilerunterstützung gezielt abkoppelt.

Wobei, um das noch einmal deutlich zu schreiben, meine Kritik jetzt speziell für den Weg gilt, der in dem Video vorgestellt wird, nicht für die Verwendung von Interfaces für den Zweck der Entkoppelung an sich.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Beiträge: 2682
Erhaltene Danke: 26



BeitragVerfasst: Di 29.11.11 23:42 
Der Code ist vermutlich nicht einfacher zu lesen, da die Abhängigkeiten praktisch nur in der Konfiguration (in einer Form oder anderen) definiert sind.

Ich würde jedoch behaupten, dass man bei gutem Languagesupport von Interfaces besseren Code schreibt. Mit besser mein ich mehr Separation of Concern, mehr Single Responsibility Principle und bessere Testability.

In Delphi habe ich die Erfahrung gemacht, dass man im Vergleich zu .NET einfach um eine Grössenordnung oder zwei weniger unit- und integrationstestet. Ich kann mir das nur mit der Umgebung, der Sprache und dem Framework erklären.

Von "Gefahren" wie "aus Versehen was gelöscht ohne zu merken" kann man nur sprechen, wenn man die Richtigkeit des Codes vor allem dadurch erkennt, dass der Code kompiliert... Das kann's ja nicht sein. Hätte man jetzt gute Tests (die man eben in einer guten Umgebung und Architektur eben relativ leicht schreibt), könnte sowas gar nicht passieren: In .NET Häusern wird häufig ein Gated-Check-In konfiguriert, sodass man nichts einchecken kann, das entweder nicht kompiliert oder irgend einen Test bricht.

Die Angst, an einer Stelle was zu ändern und an einer ganz anderen Stelle ein Problem zu kriegen, hat man vor allem dann, wenn man kein gutes Separation of Concern hat. Ohne Abstraktion z.B. über Interfaces ist die Versuchung eben viel grösser, harte Annahmen über eine abhängige Komponente zu machen.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Mi 30.11.11 11:59 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Von "Gefahren" wie "aus Versehen was gelöscht ohne zu merken" kann man nur sprechen, wenn man die Richtigkeit des Codes vor allem dadurch erkennt, dass der Code kompiliert... Das kann's ja nicht sein.
Schon, aber man kann nicht alles testen. Beispielsweise Hardware-, Netzwerk- oder öffentliche Internetschnittstellen wirst du nicht immer per Unittest erschlagen können. Und dann merkt man einen Fehler eben erst, wenn man bei einem Kunden ein Update macht, der dieses Feature auch benutzt.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Beiträge: 2682
Erhaltene Danke: 26



BeitragVerfasst: Mi 30.11.11 19:00 
Sowas kannst du überhaupt nicht unittesten. Das kannst du nur integrationstesten. Das ist zugegebenermassen etwas komplexer und aufwändiger.

Aber normalerweise sind die Libraries mit den Abhängigkeiten mit der Aussenwelt Off-the-Shelf-Software. Sowas musst du ja nicht nochmals selber testen. Der Punkt ist eben, dass dein Code nicht direkt auf die Implementation eines Netzwerkzugriffs geht sondern auf ein Interface. Dieses Interface ist im Testfall gemockt. Somit kannst du deinen gesamten Code sauber unittesten, ohne, dass jemals ein echter Netzwerkzugriff stattgefunden hat.

In einer regulierten Umgebung (z.B. medizinische Anwendung) kann und darf man eigentlich nichts dem Zufall überlassen. Da musst du jedes Requirement an Unittests, Unit-Integrationstests und Integrationstests tracen und beweisen, dass das Ding richtig tut, und dass das Ding das Richtige tut. Das ganze hat im Ernstfall auch juristische Relevanz. "Das kann ich nicht testen" gibt es da nicht, sonst kommt das ganze nicht auf den Markt ;)
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 452
Erhaltene Danke: 10

Win XP, Debian GNU/Linux
Delphi 2007 Enterprise, Java, C#
BeitragVerfasst: Mo 23.01.12 12:30 
Zum Thema ein Artikel von Nick Hodges, den ich hier einmal unkommentiert verlinken möchte.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Mo 23.01.12 13:12 
Ja, den hatte ich auch heute Morgen schon gelesen. Im Grunde ist das das gleiche wie im Video, nur in Schriftform.

Ich hatte mittlerweile auch ein wenig mit dem Konzept herumgespielt. Bisher hatte ich wenige positive Erlebnisse. Einerseits macht es das ganze ziemlich aufwendig. Andererseits fallen mir für bisher leicht machbare Zuordnungen von Strukturen keine adäquaten Möglichkeiten ein das nur mit Interfaces so einfach umzusetzen. Es geht zwar, aber es sieht nicht schön aus.

Im Moment hat sich nur der Codeumfang ca. verdoppelt und das Programm ist spürbar langsamer ohne dass ich bisher einen besonderen Mehrwert sehe. :nixweiss:

Naja, wenn ich mal Zeit habe, schreibe ich das ganze einfach mal auf. Vielleicht hat ja dann jemand ein paar schlaue Ideen wie man es besser machen kann...
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Beiträge: 2682
Erhaltene Danke: 26



BeitragVerfasst: Mo 23.01.12 23:02 
Naja, ich kann mich nur wiederholen: In Delphi würde ich würde davon abraten. In Delphi mach ich das nie. In .NET mach ich das fast immer. Der Unterschied ist der schlechte Language und IDE Support für Interfaces in Delphi und Libraries für Dependency Injection.

Der Blogeintrag ist mässig gut und leider relativ einseitig. Als ob Interfaces die Welt retten könnten und in Delphi keine Probleme mit sich brächten. Ich habe das Gefühl, er hat grad die Interfaces entdeckt und ist noch ganz ausser sich. Nach dem vierten Satz in folgendem Stil musste ich schon etwas schmunzeln...
Zitat:
there is one bottom line reason why you should use interfaces in Delphi: They They provide a very thin – but very powerful -- abstraction to your code. That’s why.

Zitat:
A good developer codes against abstractions, and not implementations.

Zitat:
all the cool kids are doing interfaces, and you want to be part of the cool kid group, right?

Zitat:
And we all know that loosely coupled code is good. So interfaces help produce good code.


Eigentlich sollte man richtige und gute Gründe für etwas haben. Einfach so ein Prinzip anwenden, weil es "cool" ist, ist schlecht. Sonst passiert genau das, was jaenicke erzählt: Man hat etwas übertrieben gesprochen am Schluss doppelt so viel Code, der halb so schnell läuft und schwieriger zu verstehen ist -- und weiss nicht einmal, wofür.

In .NET ist für mich der Hauptgrund für die generelle Verwendung von Interfaces das Testen, zusammen mit einem guten Mock Framework ist das super. Was für mich Loosely Couple Code bringt ist aber vor allem Inversion of Contorl in Form von Dependency Injection. Ohne Garbage Collection ist Depdenency Injection mühsam, genauso die langsame Referenzzählung, und das ohne Support von Weak References und Events. Ausserdem gibt's keine guten und verbreiteten Mock oder DI Frameworks. In Delphi muss ich zu viele Kompromisse eingehen. Naja. Das gilt für mich mittlerweile eigentlich für die ganze Sprache ;)
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Di 24.01.12 07:02 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Ausserdem gibt's keine guten und verbreiteten Mock oder DI Frameworks.
Nick Hodges macht ja für dieses Werbung, worum es auch in dem Video ging:
code.google.com/p/delphi-spring-framework/

Für diesen Beitrag haben gedankt: baka0815
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 452
Erhaltene Danke: 10

Win XP, Debian GNU/Linux
Delphi 2007 Enterprise, Java, C#
BeitragVerfasst: Di 24.01.12 14:02 
@Jaenicke: Danke für den Link zum Spring4Delphi!

Ich würde gern mehr zur Referenzzählung von Interfaces wissen.
Was Nick Hodges da schreibt klingt nach: Nutze Interfaces und du brauchst dich nie wieder um die Laufzeit von Objekten kümmern.
Wenn man damit also wirklich (zuverlässig) auf try..finally verzichten könnte, wäre das doch eine feine Sache, oder?
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 15840
Erhaltene Danke: 741

XP, W7 x64 (Chrome, IE9, FF), Debian, (OSX 10.7)
RAD XE 2, Java (NB), C++, C# (VS 2010), JS/HTML, PHP, Lazarus
BeitragVerfasst: Di 24.01.12 14:12 
Theoretisch ja, aber praktisch möchte ich das gar nicht immer. In C# ärgere ich mich auch bisweilen über den Garbage Collector und in Java noch öfter. Bei relativ überschaubaren Tools ist das in der Tat sehr praktisch, aber wenn dann größere Speichermengen aufgrund des Scopes der Variable erst viel später freigegeben werden, ist das nicht so toll. Das ist vor allem bei Delphi ein Problem, da eben ein echter Garbage Collector fehlt.

Ich muss aber sagen, dass Interfaces in den aktuellen Delphiversionen sehr gut funktionieren. Das heißt man kann durchaus gut so arbeiten. Wenn man denn einen Vorteil daraus ziehen kann...
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Moderator
Beiträge: 2837
Erhaltene Danke: 182

Win 2000, Win XP
Delphi 7, Turbo Delphi Exp.
BeitragVerfasst: Di 24.01.12 17:38 
Wer mal sehen möchte, wie schön Code mit Interfaces selbst in Delphi werden kann, darf sich gerne mal die Standard Interface Library angucken. Man merkt sehr, dass die Entwickler die positiven Neuerungen aus C# bzw. der CLR zurückklauen wollten.

Damit gearbeitet hab ich noch nicht, aber die Samples sehen sehr elegant aus - anders als man das von Delphi sonst kennt.

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
Ich code EdgeMonkey -~==~- #ee-lounge in Freenode
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
home home