Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Fluent Interface - keine Vererbung möglich? (https://www.delphipraxis.net/194212-fluent-interface-keine-vererbung-moeglich.html)

hschmid67 29. Okt 2017 14:47

Delphi-Version: 5

Fluent Interface - keine Vererbung möglich?
 
Hallo Zusammen,

ich bin gerade auf ein Problem gestoßen und glaube, dafür gibt es keine elegante Lösung. Aber vielleicht kommt Ihr doch weiter als ich:

Ich habe eine Klasse gefunden, die ich recht gut finde, und diese ist als Fluent Interface implementiert (es geht um Cesar Romeros Rest Client). Wirklich schick für Rest-Aufrufe!

Aber wie das so ist, es fehlt doch immer etwas, was man gerne hätte:?, und deshalb würde ich die Klasse gerne erweitern. Doch das scheint mit einem Fluent Interface nicht zu funktionieren. Das Problem liegt vereinfacht wohl daran:

Delphi-Quellcode:
TKlasseA = class
  function TuEtwas: TKlasseA;
end;

TKlasseB = class(TKlasseA)
  function TuEtwasAnderes: TKlasseB;
end;
Wenn ich nun die KlasseB erzeuge und aufrufe, etwa so:

Delphi-Quellcode:
Instance := TKlasseB.Create;
Instance.TuEtwas.TuEtwasAnderes;
Dann funktioniert das nicht, da
Delphi-Quellcode:
Instance
zwar beide Funktionen kennt, aber wenn ich
Delphi-Quellcode:
Instance.TuEtwas
aufrufe, erhalte ich nur TKlasseA zurück und das kennt natürlich
Delphi-Quellcode:
TuEtwasAnderes
nicht...

Kann man dann also, allgemein gesprochen, Klassen mit Fluent Interface nicht vererben? Oder gibt es doch einen Trickt?

Viele Grüße
Harald

Namenloser 29. Okt 2017 15:09

AW: Fluent Interface - keine Vererbung möglich?
 
Der Begriff "Fluent Interface" war mir zwar nicht bekannt, aber nach der Betrachtung des Wikipedia-Artikels würde ich sagen, dass es nicht geht, ohne den Source Code zu ändern.

Unter Delphi könntest du dir aber ggf. mit einem
Delphi-Quellcode:
class helper
behelfen. Auch wenn ich
Delphi-Quellcode:
class helper
eher als Hack ansehe, nicht zuletzt weil man maximal einen helper pro Klasse haben kann. Außerdem kann man glaube ich keinen neuen Felder hinzufügen, nur (nicht-virtuelle) Methoden.

Der schöne Günther 29. Okt 2017 21:39

AW: Fluent Interface - keine Vererbung möglich?
 
Was du suchst ist "Koviarianz bei Rückgabetypen" - Also dass die Rückgabe von
Delphi-Quellcode:
TuEtwas()
in Vererbungsrichtung weiter eingeschränkt werden kann: Während TKlasseA.TueEtwas() ein TKlasseA zurückgibt könnte TKlasseB.TuEtwas() doch ein TKlasseB zurückgeben da TKlasseB doch nur eine Unterklasse von TKlasseA ist.

In Delphi leider nicht möglich :(

Redeemer 30. Okt 2017 07:59

AW: Fluent Interface - keine Vererbung möglich?
 
TuEtwas sieht irgendwie aus wie ein halber Konstruktor (der ja immer sich selbst zurückgibt), aber das geht auch nicht, weil ein Konstruktor eine class function ist, oder?

Der schöne Günther 30. Okt 2017 08:29

AW: Fluent Interface - keine Vererbung möglich?
 
TuEtwas() wird sich selbst zurückgeben. Ein Beispiel in der Delphi-Bibliothek ist der TStringBuilder:

Delphi-Quellcode:
myStringBuilder := TStringBuilder.Create();
try
   myStringBuilder
      .Append('Hallo Welt')
      .AppendLine()
      .Append(42)
      .Replace('Hallo', 'Tschüss')
      .AppendLine();

   someText = myStringBuilder.ToString();
finally
   myStringBuilder.Destroy();
end;

hschmid67 31. Okt 2017 18:07

AW: Fluent Interface - keine Vererbung möglich?
 
Danke für Eure Antworten - Es scheint also so, dass ich mit meinen Vermutungen recht hatte, und eine Vererbung nicht möglich ist. Schade!

Aber danke für's Mitdenken!

Viele Grüße
Harald

Der schöne Günther 31. Okt 2017 18:28

AW: Fluent Interface - keine Vererbung möglich?
 
Je nachdem was du vorhast würde ich es aber, wie vorgeschlagen, mit
Delphi-Quellcode:
class helper
machen. Solange man es nicht übertreibt...

hschmid67 31. Okt 2017 18:32

AW: Fluent Interface - keine Vererbung möglich?
 
Ja, danke nochmal für den Hinweis. Vielleicht sollte ich doch mal drüber nachdenken?! Ich habe die Class Helper eigentlich als "unbrauchbar" für mich eingestuft und grundsätzlich abgetan. Da man nur einen Helper verwenden kann und in größerem Code meiner Meinung nach keinen Überblick darüber behalten kann, welcher Helper denn ggf. aktiv wird, schien es mir kein brauchbares Programmiermittel und daraus resultierend kein guter Code zu sein... Aber, vielleicht sollte ich doch nochmal unvoreingenommen dran gehen?

Viele Grüße

Der schöne Günther 31. Okt 2017 19:11

AW: Fluent Interface - keine Vererbung möglich?
 
Helper sind keine Allzweck-Waffe. Klar, für Basistypen wie
Delphi-Quellcode:
String
oder
Delphi-Quellcode:
Integer
bringt die Delphi-RTL schon einen helper mit der alles erschlagen soll. Auch für
Delphi-Quellcode:
TDateTime
wäre sicher einer denkbar gewesen.

Aber ansonsten sind helper mMn immer ein Ausweg wenn man damit entweder die Lesbarkeit stark verbessern kann oder einen Hack braucht (Zugriff auf
Delphi-Quellcode:
protected
Elemente) - Mehr nicht. Folglich fällt mir, außer dem
Delphi-Quellcode:
TDateTime
-Beispiel kein Fall ein wo ich wirklich einen allgemeingültigen Helper erstellt hätte - Sonst immer nur für eine Unit, meinst nur speziell für eine einzelne Methode. Deshalb finde ich das "Nur ein Helper aktiv, nicht mehrere gleichzeitig" ehrlich gesagt nicht schlimm.

Wenn ich den Quelltext vom "Delphi Fluent REST Client" richtig überflogen habe dann dreht sich da ja alles um den
Delphi-Quellcode:
TRestClientRequest
- Vielleicht habe ich nur zu oberflächlich geschaut, aber ich würde das dann, je nachdem was du vorhast, vielleicht sogar komplett ohne Unterklasse von
Delphi-Quellcode:
TRestClientRequest
sondern nur über einen class helper lösen.

himitsu 31. Okt 2017 22:47

AW: Fluent Interface - keine Vererbung möglich?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1384525)
In Delphi leider nicht möglich :(

Auf Interfaces umsteigen?

Also OLE-Interface, genauer IDispatch in einem Variant verpackt.
IDispatch in einem Variant, da werden Methodenaufrufe erst zur Laufzeit aufgelöst und dem Compiler ist das egal (leider auch der Codevervollständigung von Delphi).

Delphi-Quellcode:
TKlasseA = class(..., IKlasseA )
  function TuEtwas: Variant; // hier IKlasseA oder IKlasseB wenn am Anfang als TKlasseB/IKlasseB erstellt wurde
end;

TKlasseB = class(TKlasseA, IKlasseB)
  function TuEtwasAnderes: Variant; // hier IKlasseB
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:14 Uhr.
Seite 1 von 2  1 2   

Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf