Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Schon wieder: Warum Interfaces (https://www.delphipraxis.net/190600-schon-wieder-warum-interfaces.html)

Aviator 20. Okt 2016 15:23

AW: Schon wieder: Warum Interfaces
 
Hmm, ja stimmt auch wieder. :stupid:

Was sagt denn der TE "Exilant" mittlerweile zu dem Thema? Ist das alles jetzt etwas verständlicher?

exilant 20. Okt 2016 16:28

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von Aviator (Beitrag 1351518)
Was sagt denn der TE "Exilant" mittlerweile zu dem Thema? Ist das alles jetzt etwas verständlicher?

Zunächst mal vielen Dank an alle Schreiber hier. Eine Menge Input. So eine Resonanz habe ich nicht erwartet. Das Thema treibt doch viele um. Wie weit mich das weiter gebracht hat kann ich noch nicht abschätzen. Ich muss mir das erst mal in Ruhe zu Gemüte führen. Dazu werde ich etwas Zeit brauchen. Dieser Thread wird dazu sehr nützlich sein. Danke auch besonders an stahli, der mich auf diesen Thread hingewiesen hat.

Das mit der "Verständlichkeit" war wie ich geschrieben hatte nicht so das Problem. Interfaces setze ich seit Ewigkeiten für die Office Atomation ein. Ausserdem kommuniziere ich hier mit OPC Servern (nicht UA) - das ist auch COM/DCOM und das klappt. Auch wenn die Programmierung von dem Zeugs eine Strafe ist.

Ich suche/suchte ja nach dem Nutzen von Interfaces in eigenen Anwendungen. Und in denen verzichte ich natürlich auf COM/DCOM und DLLs solange ich es selbst in der Hand habe. Interfaces als wie Lemmy es sagt "logische oder zwingende Weiterentwicklung klassicher OOP" zu sehen: Da muss ich erstmal hinkommen.

Ich denke das in einigen Beiträgen in diesem Thread echtes Gold steckt und mich die Nützlichkeit von Interfaces in eigenen Anwendungen jenseits von COM erkennen lässt. Ich werde lesen, testen und wieder lesen.

Nochmal vielen Dank an alle. Ich werde mich bestimmt noch zu dem Thema melden sowie ich das hier durchgeackert habe. Ich denke da werden noch ein paar Dinge offen bleiben...

stahli 20. Okt 2016 16:44

AW: Schon wieder: Warum Interfaces
 
Freut mich. :-)

Ein bisschen kann man das vielleicht auch sehen wie die Sinnhaftigkeit der Trennung von Businesslogik und GUI. (Das werden ja hier alle Beteiligten für nützlich halten.)

Interfaces trennen dann verschiedene Teile eines Moduls nochmal klarer voneinander ab und reduzieren noch weitere vorhandene Abhängigkeiten (und verbessern weiter die Übersichtlichkeit).

bra 20. Okt 2016 16:57

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von DeddyH (Beitrag 1351516)
Delphi-Quellcode:
Supports(Test, IIntf2, Intf2);
if Assigned(Intf2) then
  Intf2.SomeMethod3;

Könnte man das nicht kürzen?

Delphi-Quellcode:
if Supports(Test, IIntf2, Intf2) then
  Intf2.SomeMethod3;

Aviator 20. Okt 2016 16:59

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von bra (Beitrag 1351531)
Zitat:

Zitat von DeddyH (Beitrag 1351516)
Delphi-Quellcode:
Supports(Test, IIntf2, Intf2);
if Assigned(Intf2) then
  Intf2.SomeMethod3;

Könnte man das nicht kürzen?

Delphi-Quellcode:
if Supports(Test, IIntf2, Intf2) then
  Intf2.SomeMethod3;

Siehe Beitrag von DeddyH. Da hat er es genau so gemacht.

DeddyH 20. Okt 2016 17:22

AW: Schon wieder: Warum Interfaces
 
Richtig, ich wollte ja nur zeigen, dass es so oder so geht, je nach persönlicher Vorliebe :)

hanvas 20. Okt 2016 17:31

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von exilant (Beitrag 1351525)

Ich suche/suchte ja nach dem Nutzen von Interfaces in eigenen Anwendungen. Und in denen verzichte ich natürlich auf COM/DCOM und DLLs solange ich es selbst in der Hand habe. Interfaces als wie Lemmy es sagt "logische oder zwingende Weiterentwicklung klassicher OOP" zu sehen: Da muss ich erstmal hinkommen.

Eine Sache die schnell einleuchtet ist das man Methoden von Klassen auf Objekte die aus unterschiedlichen Klassenhyrarchien stammen anwenden kann. Ich finde TFortbewegung2 einfacher zu warten, gut zu verstehen und typsicherer als TFortbewegung1.

Code:

type IBeweglich = interface
      end;

     TAuto = class(TSache,IBeweglich)
     end;

     TVogel = class(TLebendig,IBeweglich)
     end;

     TFortbewegung1=class(TAktion)
     public
      function begwege(was : TAuto) : Integer; overload;
      function begwege(was : TLebendig) : Integer; overload;
     end;

     TFortbewegung2=class(TAktion)
      function begwege(was : IBeweglich) : Integer;
     end;
cu Ha-Jö

frapo 20. Okt 2016 17:41

AW: Schon wieder: Warum Interfaces
 
Vielleicht findet man leichter Zugang zu dem Thema, wenn man sich parallel dazu Entwurfsmuster mal ansieht? z.b. https://www.philipphauer.de/study/se...n/strategy.php.

Ein Klassiker für mich wäre eine Anwendung, die verschiedene "Datensenken" verfügbar machen möchte. Beispielsweise möchte man das Speichern in einer oder mehreren Datenbanksystemen möglich machen und/oder auch das Speichern als Plaintext, XML-File, CSV-Datei etc.

Da bietet sich doch die Nutzung von Interfaces gerade zu an.

einbeliebigername 20. Okt 2016 19:00

AW: Schon wieder: Warum Interfaces
 
Hallo,

Zitat:

Zitat von bra (Beitrag 1351447)
Der einzige Grund, wieso ich bisher bewusst ein Interface eingesetzt habe (von COM und sowas mal abgesehen), war, dass ich Mehrfachvererbung für eine Klasse brauchte.

Was du meins ist, du brauchtest eine Mehrfachschnittstellenvererbung. Die ist ja auch relativ einfach umzusetzen.

Zitat:

Zitat von bra (Beitrag 1351447)
Ist mir bis heute unverständlich, wieso Delphi sowas nicht unterstützt.

Was du jetzt meins ist die Mehrfachverhaltensvererbung, welche leider nicht so trivial ist.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Ich finde, Interface-Programmierung verhält sich zu OOP wie die OOP zur prozeduralen Programmierung.

Jetzt fällt mir sofort "Objektorientierte Softwareentwicklung" aus Unizeiten ein. Was hat uns der OOS-Vorleser immer an den Kopf geworfen.
Zitat:

OOP ist nur syntaktischer Zucker.
Ja und da haben wir mit einer nicht OOP-fähigen Programmiersprache OOP-Programmiert und somit das Konzept hinter OOP kennen gelernt.

Eine Klasse besteht aus einer Schnittstelle und deren Implementierung. Eine Klasse kann die Schnittstelle zusammen mit deren Implementierung einer anderen Klasse erben. Und das Vererben der Implementierung ist OOP. Ein Interface ist somit quasi eine halbe Klasse, nämlich die Schnittstelle. Der Vorteil von OOP ist die Codereduzierung. Ohne OOP müsste man bei einem TNumberEdit größtenteils das komplette TEdit bis runter zu TObject nochmal neu implementieren. Mit OOP ist das nur eine klitzekleine Vererbung mit dem überschreiben einer virtuellen Methode. Interfaces bringen keine weitere Codereduzierung. Falsch eingesetzt erhöhen sie sogar die Menge an Code.

Und hiermit stelle ich an die Interface-Prediger mal eine Aufgabe. Baut doch mal TNumberEdit, TEdit bis runter zu TObject Interface-like nach ohne Klassenvererbung und ohne die Klassen aus VCL/RTL einzusetzen. Aber bitte mit Implementierung. Mich würde mal interessieren wie das denn aussehen würde.

Interface-Programmierung kann sich nicht zu OOP verhalten, weil sie teil dieser ist.


Zitat:

Zitat von Lemmy (Beitrag 1351449)
Grundsätzlich kannst Du jedes Problem auch ohne Interfaces und ohne OOP lösen.

Ja, aber auch ohne Hochsprache und Assembler.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Und keinen interessiert es.

Doch, denn das wie ist entscheidend. Die Vorteile der Hochsprachen haben dazu geführt das sie sich durchgesetzt haben. Bei OOP ist es das gleiche.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Genauso wenig wie

Delphi-Quellcode:
type
  TFoo = class(TObject)
  public
    procedure DoFoo; //mit 1.000 Zeile Code
  end;
objektorientierte Programmierung ist,

Wieso ist das kein OOP. Selbst ein schlichtes
Delphi-Quellcode:
programm Test;
uses
  System.SysUtils;
var
  X: TBytes;
begin
  X:= TEncoding.UTF8.GetBytes('Test');
end;
ist OOP, wegen dem
Delphi-Quellcode:
TEncoding.UTF8.GetBytes
.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
ist die Definition eines Interfaces, die Implementierung und Verwendung davon automatisch auch eine sinnvolle Verwendung eines Interfaces, weil es oft schlicht und ergreifend nur mehr Arbeit ist aber keinen Vorteil bietet, weil man die Technik falsch anwendet bzw. im falschen Kontext.

Das habe ich jetzt auch nach mehrmals lesen nicht verstanden.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Interfaces sind eine logische Weiterführung der OOP, vielleicht müsste man auch sagen, eine zwingende Weiterführung.

Nein. Interfaces sind Teil von OOP.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Aber es ist wie gesagt nicht damit getan ein

Delphi-Quellcode:
type
  IFoo = Interface
    procedure DoFoo;
  end;
zu schreiben und zu Jubeln "Ich kann Interfaces", sondern dann folgen automatisch auch weiter Punkte die dann wichtig werden, denn Interfaces werfen wie vieles andere auch, mehr Fragen auf, als sie beantworten :-) Als ein Stichpunkt werfe ich hier nur mal Dependency Injection ein.


Der große Vorteil von Interfaces eröffnet sich erst in etwas komplexeren Systemen, in denen div. Klassen miteinander kommunizieren müssen. Hier hast Du die Möglichkeit, dass diese Klassen weiterhin miteinander arbeiten könne, sich aber gegenseitig nicht mehr persönlich kennen müssen:

Das bekommst du aber auch ohne Interface hin. Ich sage nur reine abstrakte Klassen. Die haben mit Interfaces was gemeinsam. Denen fehlt auch die Implementierung der Schnittstelle.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Delphi-Quellcode:
TAdresse = class()
...
public
  function GetAnrede: String;
  function GetName1: String;
  function GetName2: String;
  function GetStrasse: String;
....
end;

TPerson = class()
private
  FName, FVOrname: String;
  FStrasse: String;
....
public
  property Adresse: TAdresse read FAdresse;
Und damit wir einen Konsumenten haben:

Delphi-Quellcode:
TBrief = class()
public
  procedure ErstelleBrief(Empfaenger: TAdresse);
end;
hier hast Du einen harte Kopplung wie sie in div. Projekten vorkommt und alles ist OK.
Willst Du jetzt aber TBrief durch einen Unittest jagen hast Du das Problem, dass Du zwingend auch eine Instanz von TAdresse erzeugen und übergeben musst. Kein Problem, solange TAdresse keine weiteren Abhängigkeiten hat. Sobald das System und das BOM komplexer werden, wirst Du hier immer mehr abhängige Klassen vorbereiten müssen, instanziieren müssen bis du zu dem Punkt kommst: Unittests sind scheiße, weil Du für eine Zeile Testcode, 10, 20 Zeilen Code für die Instanziierung und für die Aufräumaktionen brauchst. Und du merkst nicht, dass eigentlich dein Modell ein Problem hat.

Was hindert dich daran erst mal eine rein abstrakte klasse TBasisAdresse zu definieren. Dann kannst du im Unittest eine schicke TUnittestAdresse bauen. Und beim Erzeugen von Objekten helfen Klassenreferenzen, die richtige Klasse zu verwenden. Und sollte es auch noch nach Jahren richtig sein, das bei allen Kindern ein gewisser Teil der Implementierung gleich ist, kann dieser ruhig in der Basis-Klasse verweilen und braucht somit nur einmal Implementiert und einmal gewartet werden.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Mit Interfaces sieht das ganze so aus:

Delphi-Quellcode:
IAdresse = Interface
  function GetAnrede: String;
  function GetName1: String;
  function GetName2: String;
  function GetStrasse: String;
end;

TPerson = class()
private
  FName, FVOrname: String;
  FStrasse: String;
....
public
  property Adresse: IAdresse read FAdresse;
Und damit wir einen Konsumenten haben:

Delphi-Quellcode:
TBrief = class()
public
  procedure ErstelleBrief(Empfaenger: IAdresse);
end;
Nun kann TPerson selbst entscheiden, welche Implementierung von IAdresse (es kann mehrere geben) für seinen Zwecke am besten ist. TBrief ist das aber völlig egal, durch das Interface weiß die Klasse, dass die vertraglich vereinbarten Methoden vorhanden sind und funktionieren, d.h. Du kannst TBrief dann auch damit verwenden:

Delphi-Quellcode:
type
  TStudent = class(X,IAdresse)
  ...
  public
    function GetAnrede: String;
    function GetName1: String;
    function GetName2: String;
    function GetStrasse: String;
und TStudent muss kein weiteres Element deines TPerson-Frameworks kennen, muss nicht von einer gemeinsamen Basisklasse abgeleitet werden,....

Und du musst in jeder Klasse die Implementierung komplett neu hinschreiben, ob wohl sie bestimmt zu 90% identisch sind.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Kommen wir aber nochmal zurück zur TPerson: ich habe oben geschrieben, dass TPerson entscheidet welche Implementierung von IAdresse es verwendet. Das ist aber schon wieder ein Fehler! Weil du baust dir hier wieder über die Hintertür eine harte Kopplung von 2 Klassen ein. Und genau das kann später wieder zu einem Problem werden, weil du dann an dem Punkt bis: Verflixt, jetzt wollte ich harte Kopplung vermeinden, muss aber halt irgend wo implementieren:

Delphi-Quellcode:
TPerson = class()
private
  FName, FVOrname: String;
  FStrasse: String;
....
public
  property Adresse: IAdresse read FAdresse;

...

TPerson.Create()
begin
  FAdresse := TFooAdresse.Create();
end;
Lösung für dieses Problem bietet die Dependency Injection: Ich kopple das Interface nicht an einer bestimmten Stelle mit einer konkreten Implementierung sondern biete über eine Liste (sog. Container) verschiedene Möglichkeiten an (oder vielleicht auch nur eine) wie IAdresse implementiert sein soll. TPerson instanziiert dann die IAdresse nicht selbst, sondern fragt bei der Liste an: Gib mir eine Instanz von IAdresse. Aber den Part könnte Stefan G. nun wirklich besser erklären :-)

Um diese Abhängigkeiten aufzulösen brauchst du aber nicht zwingend Interfaces. Das geht auch mit Klassenreferenzen.

Zitat:

Zitat von Lemmy (Beitrag 1351449)
wie auch bei der OOP ist auch bei Interfaces das Problem: Mit 2 Sätzen und einem einfachen Beispiel ist das nicht erklärt....

Ja, die Entscheidung Interfaces einzusetzen ist nicht einfach. Denn sie haben auch Nachteile.

Ich verwende auch Interfaces, aber sparsam. Bei mir ist das Verhältnis zwischen Interfaces und reiner Klassenvererbung gefühlt gleich dem in der VCL/RTL. Eigentlich benutze ich Interfaces nur da wo ich bei gemeinsamer Schnittstelle keine gemeinsame Vererbungslinie aufbauen kann. Für dieses Problem wünsche ich mir aber eine andere Lösung. Und jetzt mal ein Beispiel wie die andere Lösung aussehen müsste und wo Interfaces absolut nicht helfen.
Delphi-Quellcode:
Type
  TCustomLabeledControl<T: TControl>= class(T)
  strict private
    fLabel: TLabel;
  strict protected
    function GetLabelControlClass: TLabelClass; virtual;
  protected
    // Und viele override
  public
    constructor Create(AOwner: TComponent); override;
    procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
    // Und noch mehr override
  end;

  TLabeledEdit= class(TCustomLabeledControl<TEdit>);
  TLabeledComboBox= class(TCustomLabeledControl<TComboBox>);
  TLabeledMemo= class(TCustomLabeledControl<TMemo>);
  TLabeledRichEdit= class(TCustomLabeledControl<TRichEdit>);

implementation

constructor TCustomLabeledControl<T: TControl>.Create(AOwner: TComponent);
begin
  inherited;
  fLabel:= GetLabelControlClass.Create(nil); // Oder auch Self wie man mag
end;
 
function TCustomLabeledControl<T: TControl>.GetLabelControlClass: TLabelClass;
begin
  Result:= TLabeledControlManager.Instance.GetLabelControlClass(…); // Einen String, Enum, Self oder was auch immer passent ist übergeben
end;

procedure TCustomLabeledControl<T: TControl>.SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer);
begin
  inherited;
  fLabel.SetBounds(…);
end;
einbeliebigername.

Jim Carrey 20. Okt 2016 19:35

AW: Schon wieder: Warum Interfaces
 
Wenn ich das bisher richtig verstehe geht es bei Interfaces quasi vordergrundig um die Komprimierung des Codes.

Lemmy 20. Okt 2016 19:37

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von einbeliebigername (Beitrag 1351553)
Der Vorteil von OOP ist die Codereduzierung. Ohne OOP müsste man bei einem TNumberEdit größtenteils das komplette TEdit bis runter zu TObject nochmal neu implementieren. Mit OOP ist das nur eine klitzekleine Vererbung mit dem überschreiben einer virtuellen Methode. Interfaces bringen keine weitere Codereduzierung. Falsch eingesetzt erhöhen sie sogar die Menge an Code.
...
Und hiermit stelle ich an die Interface-Prediger mal eine Aufgabe. Baut doch mal TNumberEdit, TEdit bis runter zu TObject Interface-like nach ohne Klassenvererbung und ohne die Klassen aus VCL/RTL einzusetzen. Aber bitte mit Implementierung. Mich würde mal interessieren wie das denn aussehen würde.

ich bin mir sicher hier aufmerksam mit gelesen zu haben. Du bist der erste der diese Behauptung aufstellt. Wie kommst Du auf diesen Zweig? Niemand hat die Sinnhaftigkeit von Vererbung angezweifelt.


Zitat:

Zitat von einbeliebigername (Beitrag 1351553)

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Genauso wenig wie

Delphi-Quellcode:
type
  TFoo = class(TObject)
  public
    procedure DoFoo; //mit 1.000 Zeile Code
  end;
objektorientierte Programmierung ist,

Wieso ist das kein OOP.

eine monolithische Prozedur in eine Klasse packen in dem ich TFoo = Class drum herum schreibe ist keine OOP. Das ist lediglich Mehraufwand.


Zitat:

Zitat von einbeliebigername (Beitrag 1351553)
Selbst ein schlichtes
Delphi-Quellcode:
programm Test;
uses
  System.SysUtils;
var
  X: TBytes;
begin
  X:= TEncoding.UTF8.GetBytes('Test');
end;
ist OOP, wegen dem
Delphi-Quellcode:
TEncoding.UTF8.GetBytes
.

ein Methodenaufruf ist für dich OOP? Im Ernst? das ist Anwendung einer Klasse. mehr nicht.


Zitat:

Zitat von einbeliebigername (Beitrag 1351553)
Zitat:

Zitat von Lemmy (Beitrag 1351449)
Interfaces sind eine logische Weiterführung der OOP, vielleicht müsste man auch sagen, eine zwingende Weiterführung.

Nein. Interfaces sind Teil von OOP.

wäre das ein C++ Forum würde ich dir recht geben und hätte das auch nicht geschrieben. Dort bestand von Anfang an die Trennung zwischen Interface (Header) und Implementierung, das gab es in Delphi erst als es auch Interfaces gab. OOP geht in Delphi wunderbar ohne Interfaces weil alles in einer Datei implementiert wird (werden muss) die Möglichkeit das zu trennen bieten erst Interfaces. Und die waren in C++ von Anfang an so eingeplant. Daher bleibe ich dabei: Die sind die logische Fortsetzung.

Zitat:

Zitat von einbeliebigername (Beitrag 1351553)
Das bekommst du aber auch ohne Interface hin. Ich sage nur reine abstrakte Klassen. Die haben mit Interfaces was gemeinsam. Denen fehlt auch die Implementierung der Schnittstelle.


sicher bekomme ich das auch mit einer abstrakten Basisklasse hin. Was ist aber, wenn ich keine gemeinsame abstrakte Basisklasse definieren will / kann? Wenn ich keine Interfaces hätte müsste ich zwangsläufig irgend wo aus dem Framework eine gemeinsame Elternklasse raus suchen und von der einen Erben erstellen - selbst dann wenn ich das nicht will, weil ich damit Abhängigkeiten eingehe. Mit Interfaces muss ich das nicht.

Habe ich dagegen ein Interface zur Verfügung muss ich lediglich das implementieren und ich kann eine externe Funktionalität nutzen. Schau dir nochmal mein Beispiel an: TStudent muss von "Framework" um TBrief und TPErson nichts kennen, es musss lediglich IAdresse implementieren und schon kann ich die beiden Frameworks gemeinsam nutzen.

Mikkey 20. Okt 2016 20:16

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von Lemmy (Beitrag 1351559)
wäre das ein C++ Forum würde ich dir recht geben und hätte das auch nicht geschrieben. Dort bestand von Anfang an die Trennung zwischen Interface (Header) und Implementierung, das gab es in Delphi erst als es auch Interfaces gab. OOP geht in Delphi wunderbar ohne Interfaces weil alles in einer Datei implementiert wird (werden muss) die Möglichkeit das zu trennen bieten erst Interfaces. Und die waren in C++ von Anfang an so eingeplant. Daher bleibe ich dabei: Die sind die logische Fortsetzung.

Tut mir leid, wenn ich da reinrede, aber C++ hat (jedenfalls im Standard) keine Interfaces. Die sind bei C++ auch nicht erforderlich, weil es schließlich Mehrfachvererbung gibt. Tatsächlich benutzt man letztere um Interfaces abzubilden.
Die vom COM bekannten Interfaces kann man sogar mit normalem C implementieren und nutzen.

Lemmy 20. Okt 2016 20:27

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von Mikkey (Beitrag 1351561)
Zitat:

Zitat von Lemmy (Beitrag 1351559)
wäre das ein C++ Forum würde ich dir recht geben und hätte das auch nicht geschrieben. Dort bestand von Anfang an die Trennung zwischen Interface (Header) und Implementierung, das gab es in Delphi erst als es auch Interfaces gab. OOP geht in Delphi wunderbar ohne Interfaces weil alles in einer Datei implementiert wird (werden muss) die Möglichkeit das zu trennen bieten erst Interfaces. Und die waren in C++ von Anfang an so eingeplant. Daher bleibe ich dabei: Die sind die logische Fortsetzung.

Tut mir leid, wenn ich da reinrede, aber C++ hat (jedenfalls im Standard) keine Interfaces. Die sind bei C++ auch nicht erforderlich, weil es schließlich Mehrfachvererbung gibt. Tatsächlich benutzt man letztere um Interfaces abzubilden.
Die vom COM bekannten Interfaces kann man sogar mit normalem C implementieren und nutzen.

Ich gebe zu, dass ich kein C++ Profi bin, aber in C++ gibt es Headerdateien und es wird empfohlen Header und Implementierung zu trennen. Oder bin ich da auf dem Holzweg?

frapo 20. Okt 2016 20:49

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von Jim Carrey (Beitrag 1351558)
Wenn ich das bisher richtig verstehe geht es bei Interfaces quasi vordergrundig um die Komprimierung des Codes.

Eigentlich überhaupt nicht.

Interfaces und somit OOP stehen für ein Paradigma, dass Wartbarkeit und Erweiterbarkeit, sowie Architektur von Software im Fokus hat.

Siehe z.b.:
http://openbook.rheinwerk-verlag.de/oop/

Das ist kein Thema, dass man mal eben in 30 Minuten vollständig erfassen kann.

Mir kommt es in diesem Thread eh so vor, als ob man beim Begriff Interface(im Sinne von OOP), nicht von der selben Definition ausgeht.
Der eine spricht von DLL's oder einer anderen Schnittstellentechnik, der andere missbraucht Interfaces für die sogenannte Mehrfachvererbung.
Siehe dazu vielleicht: https://de.wikipedia.org/wiki/Schnit...schnittstellen

Vielleicht liegt das an der Geschichte von Pascal/Object-Pascal(als ehemals imperative Programmiersprache) und die stete Bindung an die DLL-Hell. Java sowie C# machen ja eigentlich sehr schnell verständlich, was und wofür Interfaces eingesetzt werden.

C++, ich glaube auch Perl und Phyton, sind momentan die einzigen populären Sprachen, die auf Mehrfachvererbung setzen. Es gibt Gründe dafür und auch gute Gründen dagegen. Das muss dann jeder für sich ausmachen. Ich bin da persönlich sehr zufrieden, dass Mehrfachvererbung in Java, C# und Delphi nicht möglich ist. Die Architektur einer Software ist schon kompliziert genug.

Mikkey 20. Okt 2016 20:54

AW: Schon wieder: Warum Interfaces
 
Headerdateien sind keine Interfaces. Nur, weil in Delphi der Anfang der Quelldatei sich "Interface" nennt, ist der dazu in C++ analoge Teil (die Headerdatei) noch lange keins.

Headerdateien sind dazu da, Vorwärtsdeklarationen und Extern-Deklarationen für die Verwendung der in der C++-Datei enthaltenen Implementierung bereitzustellen.

Interfaces (und bei C++ abstrakte Basisklassen) werden verwendet,
- um verschiedene Implementierungen von gleichartigem Code verwenden zu können
- um Fassaden- und Adapter-Patterns zu realisieren
- um Unit-Tests viel (!) einfacher zu machen, selbst wenn die getesteten Klassen im System "mittendrin" verwendet wird.

In Delphi wird unglücklicherweise die Interface-Verwendung mit der Referenzzählung und automatischer Freigabe gekoppelt. Deshalb wird das auch häufig missverstanden.

MyRealName 20. Okt 2016 22:27

AW: Schon wieder: Warum Interfaces
 
Ich weiss nicht, ob es genannt wurde, woltle jetzt keine 6 Seiten lesen :

Mit einem interface kann ich 2 komplett verschiedene Klassen miteinander verbinden, zum Bsp. TTreeView und TListView, da könnte man dann ein AddItem in einem interface hinzufügen und dann ohne die klasse zu kennen über das interface AddItem aufrufen.

DeddyH 21. Okt 2016 08:12

AW: Schon wieder: Warum Interfaces
 
Nach meinem Verständnis ist genau das der Sinn von Interfaces: Abstraktion. Angenommen, wir haben eine Klassenstruktur mit 2 Zweigen: TFoo und TBar. Wollen wir jetzt einer Methode eine Instanz als Parameter übergeben, welche wiederum eine Methode der übergebenen Instanz aufruft, und diese Instanz soll entweder TFoo oder TBar (oder eine Ableitung einer der beiden) sein, dann haben wir 3 Möglichkeiten:
1. Deklaration einer Basisklasse mit dieser Methode, von der sowohl TFoo als auch TBar abgeleitet werden, der Parameter ist dann vom Typ der Basisklasse
2. Eine Abfrage innerhalb der aufrufenden Methode, ob die Parameter-Instanz TFoo oder TBar ist, der Parameter ist dann vom Typ TObject
3. Definition eines Interfaces, das von irgendeiner (oder auch mehreren) Klasse innerhalb der Struktur implementiert wird und Deklaration des Parameters als Typ dieses Interfaces

2 ist die unsauberste und unflexibelste Lösung, da sind wir uns wohl einig. 1 ist ein gangbarer Weg, kann aber bei mehreren solcher Fälle schnell unübersichtlich werden und dazu führen, dass schon die Basisklasse mit Methoden überfrachtet wird, die erst weiter unten im Zweig tatsächlich benötigt werden. Und zu 3: wie war nochmal der Titel dieses Threads? :mrgreen:

einbeliebigername 21. Okt 2016 09:36

AW: Schon wieder: Warum Interfaces
 
Hallo,

Zitat:

Zitat von Jim Carrey (Beitrag 1351558)
Wenn ich das bisher richtig verstehe geht es bei Interfaces quasi vordergrundig um die Komprimierung des Codes.

Nein, komprimieren tut man den Code durch Vererbung. Interfaces falsch angewendet blähen den Code nur auf. Selbst Richtig kann dazu führen das man mehr Code hat.

Zitat:

Zitat von Lemmy (Beitrag 1351559)
Zitat:

Zitat von einbeliebigername (Beitrag 1351553)
Der Vorteil von OOP ist die Codereduzierung. Ohne OOP müsste man bei einem TNumberEdit größtenteils das komplette TEdit bis runter zu TObject nochmal neu implementieren. Mit OOP ist das nur eine klitzekleine Vererbung mit dem überschreiben einer virtuellen Methode. Interfaces bringen keine weitere Codereduzierung. Falsch eingesetzt erhöhen sie sogar die Menge an Code.
...
Und hiermit stelle ich an die Interface-Prediger mal eine Aufgabe. Baut doch mal TNumberEdit, TEdit bis runter zu TObject Interface-like nach ohne Klassenvererbung und ohne die Klassen aus VCL/RTL einzusetzen. Aber bitte mit Implementierung. Mich würde mal interessieren wie das denn aussehen würde.

ich bin mir sicher hier aufmerksam mit gelesen zu haben. Du bist der erste der diese Behauptung aufstellt. Wie kommst Du auf diesen Zweig? Niemand hat die Sinnhaftigkeit von Vererbung angezweifelt.

Da habe ich mehrere Aussagen, auch aus anderen Quellen, welche ich nicht mehr zusammen bekomme, zu dem Thema in ein Topf geworfen. Vieleicht falsch umgerührt und wieder mal etwas überspitzt. Was ich aber als Reaktion auf meine Aufgabe erwartet habe, war ein schlichtes geht nicht, weil es nicht zu schaffen ist, weil keiner so viel Zeit hat! In den Klassen steckt schon viel Code drin der durch Vererbung wiederverwendet wird.

Zusammenfassung von Daten und Methoden in Verbindung mit Vererbung ist OOP. Vererbung ist das was dabei die Wiederverwendbarkeit von Sourcecode verbessert. Die Zusammenfassung von Daten und Methoden verbessert die Verständlichkeit. Damit man so viel wie möglich Code wiederverwendet setzt man Vererbung ein wo es nur geht. Interfaces bleiben dann nur für die Spezialfälle, wo Vererbung nicht mehr funktioniert. Bei einer Schnittstelle zwischen DLL und Anwendung kommt man mit Vererbung nicht zum Ziel, da braucht man und sollte man Interfaces einsetzen. Aber bei so simplen wie TAdresse gleich mit Interface anzufangen bläht den Code nur unnötig auf.

Zitat:

Zitat von Lemmy (Beitrag 1351559)

Zitat:

Zitat von einbeliebigername (Beitrag 1351553)

Zitat:

Zitat von Lemmy (Beitrag 1351449)
Genauso wenig wie

Delphi-Quellcode:
type
  TFoo = class(TObject)
  public
    procedure DoFoo; //mit 1.000 Zeile Code
  end;
objektorientierte Programmierung ist,

Wieso ist das kein OOP.

eine monolithische Prozedur in eine Klasse packen in dem ich TFoo = Class drum herum schreibe ist keine OOP. Das ist lediglich Mehraufwand.

Die Klasse TFoo erbt zumindest was von TObject, wenn auch nicht viel. Wenn man in dem Beispiel die Elternklasse durch TForm austauscht, sieht man das deutlicher. Eine Klasse, die 99,9% des Codes von der Elternklasse erbt und durch eine einzige Zeile ein verändertes Verhalten erzeugt, ist OOP.

Zitat:

Zitat von Lemmy (Beitrag 1351559)

Zitat:

Zitat von einbeliebigername (Beitrag 1351553)
Selbst ein schlichtes
Delphi-Quellcode:
programm Test;
uses
  System.SysUtils;
var
  X: TBytes;
begin
  X:= TEncoding.UTF8.GetBytes('Test');
end;
ist OOP, wegen dem
Delphi-Quellcode:
TEncoding.UTF8.GetBytes
.

ein Methodenaufruf ist für dich OOP? Im Ernst? das ist Anwendung einer Klasse. mehr nicht.

Eine Klasse kannst du gar nicht ohne OOP anwenden, weil sie schlicht nicht existieren könnte. Und wenn man bei dem Beispiel mal genau hinter die Funktionsweise der mindesten zwei Klassen schaut, stellt man fest das dort schon sehr viel OOP (
Delphi-Quellcode:
virtual; abstract;
) bemüht wird.


Zitat:

Zitat von Lemmy (Beitrag 1351559)
Zitat:

Zitat von einbeliebigername (Beitrag 1351553)
Zitat:

Zitat von Lemmy (Beitrag 1351449)
Interfaces sind eine logische Weiterführung der OOP, vielleicht müsste man auch sagen, eine zwingende Weiterführung.

Nein. Interfaces sind Teil von OOP.

wäre das ein C++ Forum würde ich dir recht geben und hätte das auch nicht geschrieben. Dort bestand von Anfang an die Trennung zwischen Interface (Header) und Implementierung, das gab es in Delphi erst als es auch Interfaces gab. OOP geht in Delphi wunderbar ohne Interfaces weil alles in einer Datei implementiert wird (werden muss) die Möglichkeit das zu trennen bieten erst Interfaces. Und die waren in C++ von Anfang an so eingeplant. Daher bleibe ich dabei: Die sind die logische Fortsetzung.

In C++ kann man, soweit ich noch weiß, die Implementierung auch in die Header-Datei schreiben. Der Compiler verarbeitet das auch brav. Das erzeugt zwar hier und da Probleme und ist kein gutes C++. Aber man kann damit was funktionsfähig bauen. Man kann aber auch die Klasse komplett in die CPP schreiben, wie in Delphi implementation-Teil. Auch wenn man in anderen Sprachen es nicht so leicht sieht wie in Delphi, haben Klassen automatisch eine Schnittstelle (im eng. ein Interface). Und noch mal, Interfaces sind Teil von OOP. Die logische Fortsetzung von OOP sind Generics.

Zitat:

Zitat von Lemmy (Beitrag 1351559)
Zitat:

Zitat von einbeliebigername (Beitrag 1351553)
Das bekommst du aber auch ohne Interface hin. Ich sage nur reine abstrakte Klassen. Die haben mit Interfaces was gemeinsam. Denen fehlt auch die Implementierung der Schnittstelle.


sicher bekomme ich das auch mit einer abstrakten Basisklasse hin. Was ist aber, wenn ich keine gemeinsame abstrakte Basisklasse definieren will / kann?

Wenn du nicht willst, machst du in meinen Augen was falsch. Wenn es aber nicht geht, weil es aus Gründen schon verschiedene Elternklassen gibt, oder es unterschiedliche Kombinationen von Schnittstellen geben kann, dann sind aktuell Interfaces die Wahl.

Zitat:

Zitat von Lemmy (Beitrag 1351559)
Habe ich dagegen ein Interface zur Verfügung muss ich lediglich das implementieren und ich kann eine externe Funktionalität nutzen. Schau dir nochmal mein Beispiel an: TStudent muss von "Framework" um TBrief und TPErson nichts kennen, es musss lediglich IAdresse implementieren und schon kann ich die beiden Frameworks gemeinsam nutzen.

Ja ich kenne viele Beispiele. Keines geht wirklich auf den Fakt ein, dass oft größere Teile bei den Interface-Implementierungen Copy and Past sind und erklärt wie man das vermeidet. Ich setze doch selbst Interfaces ein. Nur das bei mir Interfaces die letzte Wahl sind und ich nicht mal ansatzweise Begriffe wie Interface-Programmierung oder IOP einführen würde. Ich selbst zu zwingen mich erst mal über eine Vererbungsmöglichkeit nachzudenken, denn man kann es nicht oft genug sagen, Vererbung ist das was Code reduziert.

Und schaue dir doch mal bitte mein Gegenbeispiel mit den LabeledControls an und sag mir wie die Zauberinterfaces (Auch diesen Begriff habe ich aus vielen Aussagen überspitzt zusammengesetzt) das Problem lösen. Interfaces können nicht zauber. Sie sind auch nicht die einzige Möglichkeit Abhängigkeiten aufzulösen. Sie sind sogar in gewisser Weise gefährlich.

Zitat:

Zitat von MyRealName (Beitrag 1351573)
Ich weiss nicht, ob es genannt wurde, woltle jetzt keine 6 Seiten lesen :

Mit einem interface kann ich 2 komplett verschiedene Klassen miteinander verbinden, zum Bsp. TTreeView und TListView, da könnte man dann ein AddItem in einem interface hinzufügen und dann ohne die klasse zu kennen über das interface AddItem aufrufen.

Es wurde denke ich schon angesprochen, vielleicht nicht so deutlich. Ja und das ist genau der Fall, wo man aktuell nur mit Interfaces weiter kommt. Ich wünsche mir, dass man das auch mit Vererbung lösen könnte.

Zitat:

Zitat von DeddyH (Beitrag 1351586)
2 ist die unsauberste und unflexibelste Lösung, da sind wir uns wohl einig. 1 ist ein gangbarer Weg, kann aber bei mehreren solcher Fälle schnell unübersichtlich werden und dazu führen, dass schon die Basisklasse mit Methoden überfrachtet wird, die erst weiter unten im Zweig tatsächlich benötigt werden. Und zu 3: wie war nochmal der Titel dieses Threads? :mrgreen:

Ja genau: Erst über 1. gründlich nachdenken, dann es mit 3. versuchen und wenn alle Stricke reißen, 2. verwenden. Bei 2. sollte man sehr sehr selten ankommen. Und das Verhältnis von 1. und 3. sollte deutlich zu 1. tendieren.

Was ich noch für Interfases gelten lassen würde, währ das Argument, dass man durch Interfases die Schnittstelle für eine Funktionalität deutlicher abgrenzen kann. Das müsste man aber ohne Zusätzliche Implementierung schaffen können. Also ein einfaches sinnfreies Beispiel. Man hat mehrere Formularklassen. Bei jeder will man die Caption von außen verändern können. Der Teil der Schnittstelle in der Basisklasse von den Formularklassen ist das Property Caption. Den Rest braucht man nicht für diese Aufgabe. Also könnte man jetzt mittels eines Interface den Teil abgrenzen, wie folgt:
Delphi-Quellcode:
iFormCaption= interface
  property Caption: string;
end;
TMyForm= class(TForm, iFormCaption)
end;
Die Implementierung des Interface führt nicht zu mehr Code, da das was im Interface verlangt wird bereit in der Basisklasse vorhanden ist. Leider macht Delphi da einem wieder mitunter einen dicken Strich durch die Rechnung. Bei Properties in Interfaces muss man Getter (wenn man lesen will) und Setter (wenn man schreiben will) angeben. Das führt im konkreten Beispiel dazu, dass man in jeder Formularklasse, welche iFormCaption implementiert auch den Getter und Setter implementieren muss. Die sehen aber immer identisch aus. Selbst wenn man es schafft Getter und Setter in einer Basisklasse zu implementieren, ist das noch ein unnötiges aufblähen des Codes.

einbeliebigername.

DeddyH 21. Okt 2016 09:58

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von einbeliebigername (Beitrag 1351595)
Und das Verhältnis von 1. und 3. sollte deutlich zu 1. tendieren.

Das würde ich so pauschal nicht stehen lassen, es kommt immer auf den Einzelfall an. Will ich z.B. eine Art Framework schreiben, dann sollte ich mir sehr genau überlegen, ob ich nicht lieber von Anfang an auf Interfaces setze, da wahrscheinlich die unterschiedlichsten Typen auf mich zukommen. Da wird es dann sehr schwer bis schlicht unmöglich, eine saubere Klassenstruktur hinzubekommen. Das Schöne an der Verwendung von Interfaces ist es ja gerade, dass mich der dahinterliegende Typ nicht im Geringsten interessiert und ich mich somit auf die Methoden und Eigenschaften konzentrieren kann, die im Interface zugesichert wurden.

einbeliebigername 21. Okt 2016 10:57

AW: Schon wieder: Warum Interfaces
 
Hallo,

Zitat:

Zitat von DeddyH (Beitrag 1351601)
Zitat:

Zitat von einbeliebigername (Beitrag 1351595)
Und das Verhältnis von 1. und 3. sollte deutlich zu 1. tendieren.

Das würde ich so pauschal nicht stehen lassen, es kommt immer auf den Einzelfall an. Will ich z.B. eine Art Framework schreiben, dann sollte ich mir sehr genau überlegen, ob ich nicht lieber von Anfang an auf Interfaces setze, da wahrscheinlich die unterschiedlichsten Typen auf mich zukommen. Da wird es dann sehr schwer bis schlicht unmöglich, eine saubere Klassenstruktur hinzubekommen. Das Schöne an der Verwendung von Interfaces ist es ja gerade, dass mich der dahinterliegende Typ nicht im Geringsten interessiert und ich mich somit auf die Methoden und Eigenschaften konzentrieren kann, die im Interface zugesichert wurden.

Aber wie schaffst du es, ohne über Klassenstrukturen nachzudenken, bei der Implementierung eines Interfaces in mehreren Klassen Codeduplikate zu vermeiden. Um bei dem iAdresse-Beispiel zu bleiben. Wenn man
Delphi-Quellcode:
TAdresse1= class(iAdresse)
,
Delphi-Quellcode:
TAdresse2= class(iAdresse)
und
Delphi-Quellcode:
TAdresse3= class(iAdresse)
hat, dann haben doch die drei Klassen jeweils ein
Delphi-Quellcode:
function GetFirstName: string;
. Der Funktionsrumpf sieht doch bei allen gleich aus (
Delphi-Quellcode:
 begin result:= fFirstName; end;
). Also kommt man doch zum Schluss GetFirstName in eine Basisklasse zu verschieben. Bestimmt sind 90-100% der Implementierung von iAdresse gleich. Dann kann man doch auch das Interface in der Basisklasse implementieren. Und damit wäre die Basisklasse die einzige, welche das Interface implementiert. Und somit wäre das Interface überflüssig. Sei denn du willst, das jemand auch
Delphi-Quellcode:
TFormAdresse= class(TForm, iAdresse)
machen kann, was ich softwaredesigntechnisch für eine absolute Katastrophe halte.

Schon allein der Umstand, dass ein Property im Interface einen Getter in der implementierenden Klasse benötigt, reicht für mich aus, Interfaces ausschließlich nur da einzusetzen, wo es mit Vererbung und abstrakten Klassen keine Lösung gibt.

einbeliebigername.

DeddyH 21. Okt 2016 11:01

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von einbeliebigername (Beitrag 1351611)
Aber wie schaffst du es, ohne über Klassenstrukturen nachzudenken, bei der Implementierung eines Interfaces in mehreren Klassen Codeduplikate zu vermeiden.

Das ist doch in meinem genannten Framework-Beispiel gar nicht meine Baustelle, sondern die des Anwenders. Und ich habe nie behauptet, dass man sich bei Verwendung von Interfaces keine Gedanken über die Klassenstruktur machen soll, das eine schließt doch das andere nicht aus.

stahli 21. Okt 2016 11:23

AW: Schon wieder: Warum Interfaces
 
@beliebigbenannter

Ich denke (wie DeddyH) auch, dass man beide Bereiche nicht durcheinander werfen sollte.

Vererbung ist eine Sache und die Verwendung von Interfaces eine weitere.
Für eine Vererbung ist man auf geneinsame Basisklassen beschränkt.

Mit Interfaces erreicht man eine bessere Entkopplung.

Man muss halt abwägen, wann der Mehraufwand der Interfaces Sinn macht und wann nicht.
Mir gefällt die Umsetzung der Interfaces in Delphi auch nicht so ganz.
Es wäre schön, wenn man nur

Delphi-Quellcode:
IMyIntf = Interface
  property MyProp: Integer read write;
end;
angeben müsste (wobei "read write" auch Standard sein, also weggelassen werden könnte)

Dann könnte man in der Klasse

Delphi-Quellcode:
TMyClass = class(TInterfacedObject, IMyIntf)
  ...
  property MyProp: Integer read fMyProp write fMyProp;
end;
oder auch Getter und Setter verwenden.
Das würde die Schreibarbeit, Refactoring und die Übersichtlichkeit deutlich verbessern.

So ist es jetzt leider etwas mehr Aufwand.
Aber den nehme ich u.U. gern in Kauf, weil ich das Projekt durch Verwendung von Interfaces insgesamt deutlich besser strukturieren kann.


Vererbung und Benutzung von Klassen ist ja ohne Frage ohnehin gegeben und Einzusetzen. Interfaces bringen ggf. jedoch noch einmal zusätzliche Struktur in das Projekt.

Ich würde nicht zwanghaft Interfaces einsetzen, aber bei etwas komplexeren Projekten im Regelfall schon.

einbeliebigername 21. Okt 2016 12:11

AW: Schon wieder: Warum Interfaces
 
Hallo,

Zitat:

Zitat von DeddyH (Beitrag 1351612)
Das ist doch in meinem genannten Framework-Beispiel gar nicht meine Baustelle, sondern die des Anwenders.

Das werde ich wohl nie nachvollziehen können, da bei meinen Frameworks ich der Anwender bin und diese immer aus einer konkreten Problemstellung entstehen. Und dann stecke ich bereit mitten in Klassenstrukturen und dann wird das auch damit gelöst.

Zitat:

Zitat von stahli (Beitrag 1351613)
@beliebigbenannter

Ich denke (wie DeddyH) auch, dass man beide Bereiche nicht durcheinander werfen sollte.

Ja, vieleicht übertreibe ich hier und da etwas, wie diejenigen die Interfaces als alleiniges Allheilmittel ansehen (oder es zumindest so aussehen lassen).

Zitat:

Zitat von stahli (Beitrag 1351613)
Man muss halt abwägen, wann der Mehraufwand der Interfaces Sinn macht und wann nicht.

Vollkommen ja, bloß bei mir kommt es oft so an das Interface die einzige Lösung sind und der Mehraufwand einfach unter den Teppich gekehrt wird.

Zitat:

Zitat von stahli (Beitrag 1351613)
Mir gefällt die Umsetzung der Interfaces in Delphi auch nicht so ganz.
Es wäre schön, wenn man nur

Delphi-Quellcode:
IMyIntf = Interface
  property MyProp: Integer read write;
end;
angeben müsste (wobei "read write" auch Standard sein, also weggelassen werden könnte)

Du hast recht, read write müsste der Standard sein. Dann vieleicht auch so:
Delphi-Quellcode:
iMyInterface
  property ReadWritProp: Integer;
  property ReadonlyProp: Integer readonly;
Zitat:

Zitat von stahli (Beitrag 1351613)
Ich würde nicht zwanghaft Interfaces einsetzen, aber bei etwas komplexeren Projekten im Regelfall schon.

Erst mal schauen wie breit und tief das Problem ist. Ist es er flach und breit dann Klassenstruktur. Ist es tief und schmal dann Intefaces. Beim Übergang von einem zum andern, der fließend ist, aber darauf achten das Intefaces auch Nachteile haben. Ein Nachteil kann auch sein, dass wenn man nicht selbst der Anwender ist, es dieser auch falsch benutzen kann, was einem später wieder schlimm auf den Kopf fallen kann.

einbeliebigername.

stahli 21. Okt 2016 12:18

AW: Schon wieder: Warum Interfaces
 
Ja, so kann ich mich dem anschließen. :thumb:

Ghostwalker 21. Okt 2016 12:19

AW: Schon wieder: Warum Interfaces
 
Hab grad die letzen Beiträge hier im Thread gelsen...uijuiui....

Also..mal gaaanz locker bleiben :)

Da auch einiges an Begriffen (imho) durcheinander gewürfelt wird, hier mal (nach besten Wissen) die Definitionen dafür, wie sie mir bekannt sind und von unterschiedlichster Seite auch so bestätigt wurde:


OOP:
Die logische Weiterentwicklung der Prozedurealen Programmierung (Erfinder: Prof. N.Wirt), in
dem man Daten und die Prozeduren, die diese Daten manipulieren, zu einer Einheit zusammenfasst.
Vererbung, Polymorphy usw. sind alle Teil dieses Konzepts. Erfinder ist ebenfalls Prof. N.Wirt
(siehe Oberon/Smalltalk)


Interfaces:
Interfaces sind Regeln, welche Methoden und Eigenschaften eine Klasse, die dieses Interface
unterstützen möchte, mindestens Implementieren muss. Ich kann nicht sagen, wers erfunden
hat,(nein...nicht die Schweizer von Rikola) aber da die Verbreitung von Interfaces insbesondere
durch COM/ActiveX zeitlich in den gleichen Rahmen fällt, vermute ich mal MS dahinter.


Vorteile von Interfaces:

- Übersichtlichkeit

Insbesondere wenn man mit vielen verschiedenen Klassen hantiert, erleichtern Interfaces
den Überblick zu behalten. Auch bei Teams sind Interfaces recht nützlich, da Programmierer
A nur über das Interface einer Klasse bescheid wissen muss, die Programmierer B grad baut.

- Sprachunabhängigkeit

Als "Anwender" ist mir egal, ob die Implementierung einer Interface-Klasse jetzt in C, C++ ,
Brainfuck oder was auch immer geschrieben ist, noch nicht einmal die Implementierung ist
relevant. Den "Anwender" interressieren nur die Methoden und Eigenschaften des Interfaces.


Nachteile:

- Mehr Code

Da ich die Interfaces ja irgendwo definieren muss, wird zusätzlicher Code notwendig.

- Mehr Fehlerquellen

Zumindest bei den COM-like Interfaces, wg. Referenzzählung und automatischer Freigabe.


Ob man nun auf Interfaces setzt oder nicht, muss jeder selbst entscheiden. In manchen Fällen gehts
nicht anders (Stichwort Mehrfachvererbung in Delphi). Man sollte sich aber immer bewust sein, da man sich mit den Vorteilen auch immer Nachteile einhandelt :)

frapo 21. Okt 2016 14:18

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von Ghostwalker (Beitrag 1351621)
Hab grad die letzen Beiträge hier im Thread gelsen...uijuiui....

Also..mal gaaanz locker bleiben :)

Da auch einiges an Begriffen (imho) durcheinander gewürfelt wird, hier mal (nach besten Wissen) die Definitionen dafür, wie sie mir bekannt sind und von unterschiedlichster Seite auch so bestätigt wurde:

Das geht mir schon die ganze Zeit so. Siehe meinen Post #54.

Zitat:

Zitat von Ghostwalker (Beitrag 1351621)
Interfaces:
Interfaces sind Regeln, welche Methoden und Eigenschaften eine Klasse, die dieses Interface
unterstützen möchte, mindestens Implementieren muss. Ich kann nicht sagen, wers erfunden
hat,(nein...nicht die Schweizer von Rikola) aber da die Verbreitung von Interfaces insbesondere
durch COM/ActiveX zeitlich in den gleichen Rahmen fällt
, vermute ich mal MS dahinter.

Zumindest bei den COM-like Interfaces, wg. Referenzzählung und automatischer Freigabe.

Auch hier wird meines Wissens nach der Begriff Interface nicht im Sinne der OOP angewandt. COM/ActiveX klingt doch einfach schon zu konkret. Der Begriff Interface wird hier eher aus technischer Sicht gesehen (also das Wie und nicht das Was).

In der OOP ist der Begriff Interface doch eher konzeptionell gemeint, also ohne konkrete technische Abbildung.

Drum hatte ich ja in Post #54 auch Links gepostet, die etwas Konkretisierung in das Konzept bringen könnten.

Interfaces sind aus OOP Sicht Vereinbarungen, Regeln, Verhalten, die eine implementierende Klasse einhalten muss. Dabei ist das "wie" egal, Hauptsache die Implementierung entspricht den Vorgaben. Dadurch werden die implementierenden Klassen in gewisser Hinsicht ja auch austauschbar, Stichwort Polymorphie(Vielgestaltigkeit).

Interfaces sind auch keine abstrakte Klassen, dass ist ja auch der Grund warum sie nicht zum Klassen-/Vererbungsbaum gehören. Von daher "verbietet" es sich schon konzeptionell Interfaces als Weg für die Mehrfachvererbung zu sehen.
Sprachen die Mehrfachvererbung zulassen, bietet dafür schließlich Konzepte an.

Sailor 21. Okt 2016 18:30

AW: Schon wieder: Warum Interfaces
 
Gehen wir mal so 40 Jahre zurück. Da wurde neben dem Modulkonzept das Prinzip Information Hiding (heutzutage Encapsulation, Kapselung genannt) propagiert. Der Verwender einer Komponente (ich will hier nicht Objekt sagen, um keine Verwirrung zu stiften) sollte nur noch über Funktionen/Prozeduren auf deren Funktionalität zugreifen dürfen, ohne darüber informiert zu werden, wie diese Funktionalität realisiert worden ist. Warum das? Nun, neben den öffentlichen Eigenschaften kann eine Implementierung zusätzliche, nur ihr zukommende Eigenschaften haben. Der clevere Programmierer nutzt die natürlich. Da helfen keine Verbote. Und wenn jetzt aus irgendwelchen Gründen was geändert werden muß, dann ist diese implizite Eigenschaft möglicherweise weg, eventuell mit katastrophalen Folgen. Um das zu vermeiden, ist Kapselung eines der Grundprinzipien der OOP geworden. Leider ist in den gängigen OOP-Sprachen die konsequente Trennung von Interface und Realisierung aus mir unerfindlichen Gründen "vergessen" worden. In Delphi sind zwar zarte Versuche in dieser Richtung zu erkennen. Man hätte aber z. B. Interface und Implementation auf 2 Dateien aufteilen müssen. Und in einem Interface dürfen nur die öffentlichen Funktionen/Prozeduren auftauchen. Alles andere wie Felder oder private Funktionen gehören in die Implementation. Und von C# oder Java will ich gar nicht erstreden, die haben das ganz fallengelassen. Und so weiß der Anwender immer noch, wie es gemacht wurde. Offensichtlich haben sich einige daran erinnert, daß das eigentlich verhindert werden sollte und das meines Wissens von COM herrührende Interface umgebogen, um dem Mangel abzuhelfen und stoßen nun kräftig ins Horn. Kann man machen, aber ob das zu besser lesbaren Programmen führt, wage ich zu bezweifeln. Auch die Themen Vererbung/Mehrfachvererbung, Parametrisierung von Klassen, Benutzung unterschiedlicher Implementierungen einunddesselben Interfaces in einem Programm sollten besser innerhalb einer OOP-Sprache gelöst werden.
Fazit: Ich verwende (COM-)Interfaces zur Realisierung von OOP-Interfaces nur dort, wo es angeraten erscheint, die Interna einer Implementierung vor dem Nutzer einer Klasse zu verbergen, mangels geeigneter Sprachkonstrukte. Aber vielleicht sehen wir in naher Zukunft ein Delphi 2.0, in dem das in aller Schönheit vorhanden ist.

Ghostwalker 21. Okt 2016 19:12

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von frapo (Beitrag 1351650)
Auch hier wird meines Wissens nach der Begriff Interface nicht im Sinne der OOP angewandt.

OOP hat mit Interfaces erstmal garnix zu tun (waren nie Bestandteil der OOP Definition). :)
Interfaces sind ein eigenständiges Konzept, das auf der OOP aufbaut :)

Ansonsten kann ich mich deinem Post nur anschließen frapo.

Zitat:

Zitat von Sailor
Man hätte aber z. B. Interface und Implementation auf 2 Dateien aufteilen müssen.

Warum ? Das hätte nur zu Folge, das, analog C/C++, noch mehr Dateien rumfliegen. Mal abgesehen
davon, das das nix mit dem Interface-Konzept etwas zu tun hat.

frapo 21. Okt 2016 20:35

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von Sailor (Beitrag 1351670)
Gehen wir mal so 40 Jahre zurück. Da wurde neben dem Modulkonzept das Prinzip Information Hiding (heutzutage Encapsulation, Kapselung genannt) propagiert.

Lass uns ruhig so mutig sein, 50 Jahre zurück zu gehen. Simula67 gilt, so weit ich weiß, als erste Sprache die OOP-Konzepte wie new, class und so eingeführt hat. Wie der Name schon andeutet, passierte das in den 60ern, also noch vor Pascal, Modula2 oder Oberon.. von Smalltalk mal gar nicht zu sprechen.

Zitat:

Zitat von Sailor (Beitrag 1351670)
Der Verwender einer Komponente (ich will hier nicht Objekt sagen, um keine Verwirrung zu stiften) sollte nur noch über Funktionen/Prozeduren auf deren Funktionalität zugreifen dürfen, ohne darüber informiert zu werden, wie diese Funktionalität realisiert worden ist. Warum das? Nun, neben den öffentlichen Eigenschaften kann eine Implementierung zusätzliche, nur ihr zukommende Eigenschaften haben. Der clevere Programmierer nutzt die natürlich. Da helfen keine Verbote. Und wenn jetzt aus irgendwelchen Gründen was geändert werden muß, dann ist diese implizite Eigenschaft möglicherweise weg, eventuell mit katastrophalen Folgen. Um das zu vermeiden, ist Kapselung eines der Grundprinzipien der OOP geworden.

Genau. Bei der Kapselung interessiert die konkrete Implementierung keinen.

Zitat:

Zitat von Sailor (Beitrag 1351670)
Leider ist in den gängigen OOP-Sprachen die konsequente Trennung von Interface und Realisierung aus mir unerfindlichen Gründen "vergessen" worden. In Delphi sind zwar zarte Versuche in dieser Richtung zu erkennen. Man hätte aber z. B. Interface und Implementation auf 2 Dateien aufteilen müssen. Und in einem Interface dürfen nur die öffentlichen Funktionen/Prozeduren auftauchen. Alles andere wie Felder oder private Funktionen gehören in die Implementation. Und von C# oder Java will ich gar nicht erstreden, die haben das ganz fallengelassen.

Hättest du da mal ein Beispiel? In Jave, C# und Object-Pascal(also auch Delphi) klappt die Trennung eigentlich wunderbar. Ein Interface implementiert rein gar nichts. Dort sind nur Definitionen oder Vereinbarungen beschrieben.
Die eigentliche Konkretisierung bzw. Implementierung findet in den Klassen statt, die dieses Interface auch benutzen bzw. implementieren.

Das ist ja auch der Sinn der Kapselung.

Anders Hejlsberg, der Schöpfer von Turbo Pascal, Delphi und C#, wird sich da was dabei gedacht haben sich bei der Entwicklung von Delphi und später C#, eher an Java als an C++ orientiert zu haben. Die genauen Beweggründe kannst du ja bei ihm erfragen.

Auch du wirst nicht abstreiten können, dass sein Konzept in der Fachwelt "relativ" anerkannt ist. Man durchforste einfach mal die Stellenanzeigen und den aktuellen Stand der universitären Lehre.
Funktionale Programmierung ist und war auch immer ein Thema, hat bisher aber nie die Masse erreicht.

Wenn du andere Konzepte, Ideen, Kritik vorlegen kannst, fände ich es klasse davon zu lesen, vor allem was du konkret damit meinst, das Interface und Implementierung nicht voneinander getrennt sind, in deinen Worten "vergessen" wurden.

Zitat:

Zitat von Sailor (Beitrag 1351670)
...und das meines Wissens von COM herrührende Interface umgebogen...
Fazit: Ich verwende (COM-)Interfaces zur Realisierung von OOP-Interfaces

[/QUOTE]

Und da haben wir wieder COM etc. Das hat alles erstmal nichts mit OOP zu tun!

Interface(Schnittstelle) scheint einfach ein überstrapazierter Begriff zu sein und für alles zu stehen.. für manch einen.
Natürlich steht Schnittstelle erst mal für alles mögliche. In den 80ern unter TP hat man Schnittstellen programmiert um Drucker zu steuern, um beispielsweise auf DBase-Files zugreifen zu können etc. Das hatte aber alles nichts mit Interfaces im Sinne der OOP zu tun :/

Es gibt Unterschiede zwischen technischer und konzeptioneller Sicht.

COM, ActiveX, Dll sind übrigens ein Konzept eines Betriebssystems.. soweit ich weiß. Dennoch funktioniert die OOP auf jeder Plattform, weil sie einfach als Konzept was völlig anderes darstellt, als API-Calls oder so was zu verwursten.

frapo 21. Okt 2016 20:36

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von Ghostwalker (Beitrag 1351673)
Zitat:

Zitat von frapo (Beitrag 1351650)
Auch hier wird meines Wissens nach der Begriff Interface nicht im Sinne der OOP angewandt.

OOP hat mit Interfaces erstmal garnix zu tun (waren nie Bestandteil der OOP Definition). :)
Interfaces sind ein eigenständiges Konzept, das auf der OOP aufbaut :)

Hättest du dazu Quellen, gerne auch Literatur?

stahli 21. Okt 2016 21:10

AW: Schon wieder: Warum Interfaces
 
Ach manno...

Eigentlich ging es darum, dass Neulinge die Verwendung von Interfaces (unter Delphi) besser verstehen wollten.
Die aktuelle Diskussion dürfte eher wieder zur vollständigen Verwirrung beitragen.

Vielleicht wäre das in einem eigenständigen Interface-Philosophie-Thread besser aufgehoben...

einbeliebigername 21. Okt 2016 21:22

AW: Schon wieder: Warum Interfaces
 
Hallo,

Zitat:

Zitat von Sailor (Beitrag 1351670)
Gehen wir mal so 40 Jahre zurück. Da wurde neben dem Modulkonzept das Prinzip Information Hiding (heutzutage Encapsulation, Kapselung genannt) propagiert. Der Verwender einer Komponente (ich will hier nicht Objekt sagen, um keine Verwirrung zu stiften) sollte nur noch über Funktionen/Prozeduren auf deren Funktionalität zugreifen dürfen, ohne darüber informiert zu werden, wie diese Funktionalität realisiert worden ist. Warum das? Nun, neben den öffentlichen Eigenschaften kann eine Implementierung zusätzliche, nur ihr zukommende Eigenschaften haben. Der clevere Programmierer nutzt die natürlich. Da helfen keine Verbote. Und wenn jetzt aus irgendwelchen Gründen was geändert werden muß, dann ist diese implizite Eigenschaft möglicherweise weg, eventuell mit katastrophalen Folgen. Um das zu vermeiden, ist Kapselung eines der Grundprinzipien der OOP geworden.

Ja, dank der Sichtbarkeit kann man mit OOP Funktionalität vor anderen Verbergen.

Zitat:

Zitat von Sailor (Beitrag 1351670)
Leider ist in den gängigen OOP-Sprachen die konsequente Trennung von Interface und Realisierung aus mir unerfindlichen Gründen "vergessen" worden. In Delphi sind zwar zarte Versuche in dieser Richtung zu erkennen. Man hätte aber z. B. Interface und Implementation auf 2 Dateien aufteilen müssen.

Wieso müssen jetzt dafür unbedingt Klassen-Interface und Implementierung getrennt werden?

Zitat:

Zitat von Sailor (Beitrag 1351670)
Und in einem Interface dürfen nur die öffentlichen Funktionen/Prozeduren auftauchen. Alles andere wie Felder oder private Funktionen gehören in die Implementation.

Das ist allerdings ein Punkt den ich auch in Delphi vermisse. Wobei es auch so wie in C# um gesetzt sein kann. Also entweder man verzichtet auf interface-Teil und implementiation-Teil und arbeitet mit public und privat. Dann müsste man die Uses aber aufs gesamte Modul verteilen können. Oder aber man erlaubt, dass eine Klassendefinition im interface-Teil angefangen und im implementation-Teil fortgesetzt werden kann. Ich würde zu letzteres tendieren. Dann hätte man mittels include ein Art Partielle-Klassen-Konzept für Arme.

Zitat:

Zitat von Sailor (Beitrag 1351670)
Und von C# oder Java will ich gar nicht erstreden, die haben das ganz fallengelassen.

Woraus schließt du das? Zu Java kann ich nicht so viel sage, da zu lange her. Aber Java und auch C# kennen auch Sichtbarkeit.

Zitat:

Zitat von Sailor (Beitrag 1351670)
Und so weiß der Anwender immer noch, wie es gemacht wurde.

Wodurch erfährt der Anwender wie es gemacht wurde?

Zitat:

Zitat von Sailor (Beitrag 1351670)
Offensichtlich haben sich einige daran erinnert, daß das eigentlich verhindert werden sollte und das meines Wissens von COM herrührende Interface umgebogen, um dem Mangel abzuhelfen und stoßen nun kräftig ins Horn.

Ich glaube Interfaces wurden wegen etwas anderem eingeführt.

Zitat:

Zitat von Sailor (Beitrag 1351670)
Kann man machen, aber ob das zu besser lesbaren Programmen führt, wage ich zu bezweifeln. Auch die Themen Vererbung/Mehrfachvererbung, Parametrisierung von Klassen, Benutzung unterschiedlicher Implementierungen einunddesselben Interfaces in einem Programm sollten besser innerhalb einer OOP-Sprache gelöst werden.
Fazit: Ich verwende (COM-)Interfaces zur Realisierung von OOP-Interfaces nur dort, wo es angeraten erscheint, die Interna einer Implementierung vor dem Nutzer einer Klasse zu verbergen, mangels geeigneter Sprachkonstrukte. Aber vielleicht sehen wir in naher Zukunft ein Delphi 2.0, in dem das in aller Schönheit vorhanden ist.

Dem stimme ich zu.

DeddyH 21. Okt 2016 21:23

AW: Schon wieder: Warum Interfaces
 
@stahli: :thumb:

frapo 21. Okt 2016 21:30

AW: Schon wieder: Warum Interfaces
 
Hm.. hast wohl leider recht stahli.

Vielleicht sollte ich die drei Links aus #48 und #54 einfach noch mal posten. Da steht ja eigentlich alles drin, was man wissen sollte, wenn man sich für das Thema interessiert.

http://openbook.rheinwerk-verlag.de/oop/
https://de.wikipedia.org/wiki/Schnit...schnittstellen
https://www.philipphauer.de/study/se...n/strategy.php.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:59 Uhr.
Seite 2 von 2     12   

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