Delphi-PRAXiS
Seite 4 von 8   « Erste     234 56     Letzte »    

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)

DeddyH 20. Okt 2016 13:37

AW: Schon wieder: Warum Interfaces
 
Eine goldene Regel dafür kenne ich auch nicht, aber je dynamischer (besonders im Hinblick auf die Klassentruktur) und/oder offener (im Hinblick auf externe Schnittstellen) ein Projekt wird, desto sinnvoller wird der Gebrauch von Interfaces IMO.

stahli 20. Okt 2016 13:57

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von Aviator (Beitrag 1351493)
Zitat:

Zitat von stahli (Beitrag 1351489)
Die Darstellung der Interfaces in den überwachten Ausdrücken kann man sich etwas optimieren: http://www.delphipraxis.net/189852-u...ptimieren.html

Es ist leider etwas aufwendig, aber zumindest geht es.

Ja das Thema hatte ich damals mitverfolgt. Nur habe ich mich damit nicht mehr weiter auseinander gesetzt. Muss man dann für jedes Interface einen eigenen Visualizer bauen? Das wäre ja extrem aufwendig. :shock:

Ja, wobei Vererbungen bei der Darstellung berücksichtigt werden können.
Wenn man also eine Darstellung für IMyInt hat, kann diese auch für IMyIntA und IMyIntB genutzt werden.
Wobei man Ableitungen von Interfaces eher vermeiden sollte. Hier werden ja eher Funktionalitäten beschrieben und dabei ist es i.d.R. sinnvoll, viele kleine eigenständige Funktionalitäten (Interfaces) zu definieren als von anderen abzuleiten.

Wenn man IMyInt1 und IMyInt2 und möchte jetzt ein IMyInt3, das die beiden anderen implementiert, könnte man ja nur von einem ableiten und müsste den anderen Bereich wieder nachbilden.

Besser wäre es somit, in IMyInt3 nur die Neuerungen zu definieren und einer späteren Klasse alle drei Interfaces zuzuweisen:

TMyClass = class(TInterfacedObject, IMyInt1, IMyInt2, IMyInt3)

Also, da Vererbungen von Interfaces die Ausnahme sein werden, wäre für jedes Interface eine eigene Visualisierung zu regeln.
Das kann man aber in Form von Bedingungsprüfungen in einer Unit regeln:
if (TypeName = 'IMyInt1') then
...
if (TypeName = 'IMyInt2') then
...



Zitat:

Zitat von DeddyH (Beitrag 1351501)
Eine goldene Regel dafür kenne ich auch nicht, aber je dynamischer (besonders im Hinblick auf die Klassentruktur) und/oder offener (im Hinblick auf externe Schnittstellen) ein Projekt wird, desto sinnvoller wird der Gebrauch von Interfaces IMO.

Wenn man irgendwann zu einem Punkt kommt, dass man der einen Klasse ja noch die und die Klasse und der nächsten Klasse die und die bekanntgeben muss und vielleicht wegen Kreuzbezügen das gar nicht mehr hin bekommt, dann ist ein guter Zeitpunkt für Interfaces.

Wenn man schon bei der Planung eines Projektes zu dem Schluss kommt, dort irgendwann mal zu landen, dann sollte man gleich mit Interfaces starten.
So spart man sich den Aufwand der späteren Umstellung, da das doch auf einiges Auswirkungen hat.


Ich habe gerade ein nicht sehr umfangreiches Projekt der Einfachheit halber mit Klassen begonnen und habe mich jetzt doch entschieden, das nochmal umzustellen.
Das ist zwar etwas mehr Schreibarbeit aber der Ablauf und die Beziehungen der einzelnen Projektteile ist dadurch deutlich übersichtlicher.

Jim Carrey 20. Okt 2016 14:26

AW: Schon wieder: Warum Interfaces
 
Jetzt mal für ganz Dumme, also für mich:
wann Klassen, wann Interfaces?
Das mit den Autos und Reifen habe ich kein bisschen verstanden, da ich die Gedanken dahinter nicht verstehe.

Aviator 20. Okt 2016 14:30

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von stahli (Beitrag 1351503)
Wobei man Ableitungen von Interfaces eher vermeiden sollte. Hier werden ja eher Funktionalitäten beschrieben und dabei ist es i.d.R. sinnvoll, viele kleine eigenständige Funktionalitäten (Interfaces) zu definieren als von anderen abzuleiten.

Du hast mir gerade einen Anreiz gegeben, mein noch am Anfang stehendes Projekt nochmal etwas umzustrukturieren. Allerdings habe ich da dann gerade ein Verständnisproblem.

Folgender Fall:

Delphi-Quellcode:
IMyIntf1 = interface(IInterface)
  procedure SomeMethod1();
  procedure SomeMethod2();
end;

IMyIntf2 = interface(IMyIntf1) // Hier noch abgeleitet von IMyIntf1
  procedure SomeMethod3();
end;
Delphi-Quellcode:
TMyClass = class(TInterfacedObject, IMyIntf1, IMyIntf2) // Hier könnte man IMyIntf1 ja denke ich auch weglassen
  procedure SomeMethod1();
  procedure SomeMethod2();
  procedure SomeMethod3();
end;
Delphi-Quellcode:
TMyOtherClass = class(TObject)
type
private
  MyIntfInstance: IMyIntf2; // Hier die 2 beachten
  procedure CallInterfaceMethod;
end;

implementation

procedure TMyOtherClass.CallInterfaceMethod;
begin
  MyIntfInstance.SomeMethod1();  // Hier die 1 beachten.
end;
In dem Konstrukt mit der Ableitung des Interfaces 2 von 1 ist das oben gezeigte Beispiel kein Problem. Wenn ich aber jetzt
Delphi-Quellcode:
IMyIntf2
gesondert behandele und in TMyClass implementiere, dann erhalte ich ja eine Fehlermeldung, dass
Delphi-Quellcode:
SomeMethod1()
in dem Kontext nicht verfügbar ist.

Nur wie löse ich jetzt das Problem? Ich will ja jetzt nicht so viele Interfacevariablen in meiner Klasse anlegen, wie meine Interfaceklasse Interfaces importiert. Das halte ich für sehr umständlich. Ich kenne zwar vom Hören die Methode Supports(), weiß aber nicht, in wiefern das darauf anzuwenden ist.

Hat da jemand einen Tipp?

Sherlock 20. Okt 2016 14:40

AW: Schon wieder: Warum Interfaces
 
Ganz wichtig, @Jim Carey: Klassen IMMER! Interfaces dann wenn es sinnvoll ist (darüber streiten sich dann die Experten ;)) Ein Interface ersetzt keine Klasse, Interfaces sind "nur" Vorschriften darüber wie wirkliche Implementierungen auszusehen haben.

Sherlock

Jim Carrey 20. Okt 2016 14:42

AW: Schon wieder: Warum Interfaces
 
Zitat:

Zitat von Sherlock (Beitrag 1351507)
Klassen IMMER! Interfaces dann wenn es sinnvoll ist

Mit der Antwort kann ich etwas anfangen und bestätigt mich in meiner Meinung, nicht alles sofort auf Interfaces umstellen zu müssen, nur weil es sie gibt :P

Danke.

DeddyH 20. Okt 2016 14:43

AW: Schon wieder: Warum Interfaces
 
Ich mache das normalerweise so:
Delphi-Quellcode:
type
  IIntf1 = interface
    ['{AA7958DE-7A80-4F11-A5D5-A70BB3D51320}']
    procedure SomeMethod1;
    procedure SomeMethod2;
  end;

  IIntf2 = interface
    ['{A25606F4-B121-4FA5-BF07-B40C7784FFB7}']
    procedure SomeMethod3;
  end;

  TTestClass = class(TInterfacedObject, IIntf1, IIntf2)
  public
    //IIntf1
    procedure SomeMethod1;
    procedure SomeMethod2;
    //IIntf2
    procedure SomeMethod3;
  end;

{ TTestClass }

procedure TTestClass.SomeMethod1;
begin
  ShowMessage('SomeMethod1');
end;

procedure TTestClass.SomeMethod2;
begin
  ShowMessage('SomeMethod2');
end;

procedure TTestClass.SomeMethod3;
begin
  ShowMessage('SomeMethod3');
end;

procedure TFormTest.Button1Click(Sender: TObject);
var
  Test: IIntf1;
  Intf2: IIntf2;
begin
  Test := TTestClass.Create;
  Test.SomeMethod1;
  if Supports(Test, IIntf2, Intf2) then
    Intf2.SomeMethod3;
end;

stahli 20. Okt 2016 14:58

AW: Schon wieder: Warum Interfaces
 
Genau so. :thumb:

Ich will nur noch ergänzen:

Um Supports nutzen zu können muss das Interface eine Guid haben.
Und Supports liefert im letzten Parameter automatisch den Cast des übergebenen Objektes/Interfaces auf das im zweiten Parameter übergebene Interface zurück. Oder Nil wenn Supports nicht true ist.

Ich hatte mich damit (auch?) zunächst schwer getan, aber es ist eigentlich ganz simpel.

Aviator 20. Okt 2016 15:05

AW: Schon wieder: Warum Interfaces
 
@DeddyH: Danke. Super Beispiel. :thumb: Wird aber dann doch immer etwas aufwendig wenn man immer wieder mit Supports() abfragen muss. :|

Zitat:

Zitat von stahli (Beitrag 1351513)
Um Supports nutzen zu können muss das Interface eine Guid haben.

Das wa rmir bekannt, aber gut das du das für alle anderen hier auch nochmal erwähnst. :thumb:
Zitat:

Zitat von stahli (Beitrag 1351513)
Und Supports liefert im letzten Parameter automatisch den Cast des übergebenen Objektes/Interfaces auf das im zweiten Parameter übergebene Interface zurück. Oder Nil wenn Supports nicht true ist.

Ok. Das wusste ich jetzt noch nicht, wäre aber das nächste gewesen, was ich mir angeschaut hätte. :stupid:

DeddyH 20. Okt 2016 15:15

AW: Schon wieder: Warum Interfaces
 
Ob ich nun Supports() aufrufen muss oder Dinge der Art
Delphi-Quellcode:
if MyObject is TDingens then
  TDingens(myObject).Machwas;
, komfortabler wird es nicht.

[edit] Nachtrag: stahli hat Recht, man kann das übrigens auch anders formulieren.
Delphi-Quellcode:
Supports(Test, IIntf2, Intf2);
if Assigned(Intf2) then
  Intf2.SomeMethod3;
[/edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:27 Uhr.
Seite 4 von 8   « Erste     234 56     Letzte »    

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