Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Class Helper als Lösung für zirkuläre Unit-Referenzen (https://www.delphipraxis.net/176296-class-helper-als-loesung-fuer-zirkulaere-unit-referenzen.html)

Furtbichler 26. Aug 2013 16:15

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1226249)
Interfaces muss ich in die gleiche Unit packen.

Nein, natürlich nicht. Aber hier schon (wg. zirkulärer Referenz).
[/QUOTE] Und wenn ich nun schon zwei artfremde Interfaces in eine Datei packe, kann ich auch gleich die paar Zeilen mehr für die Klassen angehen und wieder alles in einen Topf werfen.[/QUOTE]
Ich sagte doch: Eine Datei mit allen Interfaces ist allemal übersichtlicher als eine Datei mit allen Klassen.
Delphi-Quellcode:
Type
  IBesitzer = interface ...
    IHund : Hund;
  end;


  IHund = interface
   Besitzer : IBesitzer;
  end;
Und die Implementierung in separaten Dateien.

Lemmy 26. Aug 2013 20:09

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Zitat:

Zitat von Furtbichler (Beitrag 1226270)

Ich sagte doch: Eine Datei mit allen Interfaces ist allemal übersichtlicher als eine Datei mit allen Klassen.
...
Und die Implementierung in separaten Dateien.


genau. Und das Vorgehen bewahrt dann einen auch davor an Stellen "aus Versehen" die Implementierung (=Klasse) zu verwenden, wo das Interface ausreicht.

jaenicke 26. Aug 2013 20:16

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Eine andere Lösung ist eben die von mir angesprochene. Die bevorzuge ich eher. Wir benutzen normalerweise auch eine Datei pro Interface und eine pro Klasse. Mit der Lösung funktioniert das problemlos, egal ob mit Interface oder Klasse:
Delphi-Quellcode:
  TCustomDogOwner = class
  public
    procedure Schimpfen;
  end;

  TDog = class
  private
    FOwner: TCustomDogOwner;
  public
    property Owner: TCustomDogOwner read FOwner write FOwner;
  end;

  TDogOwner = class
  private
    FDog: TDog;
  public
    property Dog: TDog read FDog write FDog;
  end;

Furtbichler 26. Aug 2013 21:22

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Die habe ich auch mal verwendet, aber das ist eben ein Trick, der den Code verunstaltet. TDogOwner führt keine neuen Methoden oder Eigenschaften (mit Ausnahme der Referenz) ein. Ich muss also manchmal einen Typecast verwenden und manchmal nicht:
Delphi-Quellcode:
MyDog.Owner.Schimpfen;
if MyDog <> TDogOwner(MyDog.Owner).Dog Then
  Writeln('The dog was stolen');
Welche Klasse sollte man denn verwenden, wenn man einen Hundebesitzer instantiieren will? Das ist nicht klar, weil zwei Klassen existieren, wo eine reicht.

Dient alles nicht der Übersichtlichkeit.

Der schöne Günther 26. Aug 2013 21:44

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Zitat:

Zitat von jaenicke (Beitrag 1226306)
Wir benutzen normalerweise auch eine Datei pro Interface und eine pro Klasse. Mit der Lösung funktioniert das problemlos, egal ob mit Interface oder Klasse

Das ist, zumindest bislang, auch mein Stil 8-)

Und ich glaube auch generell in der VCL, denn irgendwie haben 3/4 aller Klassen ein "Custom" im Namen, alle die es nicht haben, sind meist abstrakt :-D

Ich bin in meinen ersten Delphi-Monaten bislang nie in die Lage gekommen, Interfaces anstatt abstrakter Klassen zu nehmen. Irgendeine konkrete Teilimplementierung ließ sich bislang immer in eine Oberklasse herausziehen. Aber wie gesagt, ob das obendrüber jetzt nun ein Interface oder eine Klasse ist kümmert ja niemanden.



Zitat:

Zitat von Furtbichler (Beitrag 1226317)
TDogOwner führt keine neuen Methoden oder Eigenschaften (mit Ausnahme der Referenz) ein. Ich muss also manchmal einen Typecast verwenden und manchmal nicht

Moment. Ich dachte, das sei nur ein Tippfehler und soll heißen
Delphi-Quellcode:
TCustomDogOwner = class(TDogOwner)
?
Dann markiere ich den TDogOwner noch als abstrakt damit mir keiner einen instanziiert.


Zitat:

Zitat von Furtbichler (Beitrag 1226317)
Delphi-Quellcode:
if MyDog <> TDogOwner(MyDog.Owner).Dog Then
  Writeln('The dog was stolen');

:mrgreen:

Lemmy 26. Aug 2013 21:54

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Zitat:

Zitat von jaenicke (Beitrag 1226306)
Eine andere Lösung ist eben die von mir angesprochene. Die bevorzuge ich eher. Wir benutzen normalerweise auch eine Datei pro Interface und eine pro Klasse. Mit der Lösung funktioniert das problemlos, egal ob mit Interface oder Klasse:


Du hast völlig recht und ist sicherlich besser als einen ClassHelper zu verwenden. Ich vermeide so was inzwischen allein für die Auflösung von zirkulären Beziehungen eine weitere Vererbungshierarchie einzuführen.

In einem größeren Projekt in dem ich das Businessmodell erstellt habe, fand ich am Ende im Basisframework (das aus ca. 6 Vererbungsebenen bestand) allein 2 Ebenen die ich nur für die Auflösung der zirkulären Referenzen eingeführt hatte. Am Ende waren die beiden Ebenen aber mit Funktionalität so erweitert worden (durch Kollegen), dass die nicht mehr so einfach zu entfernen waren.

Interfaces bieten hier die Möglichkeit einen deutlich lockeren Verbund zu erstellen. Durch die Maßgabe gegen das Interface zu implementieren und nicht gegen eine Implementierung kann ich die Implementierung auch jederzeit austauschen, z.B. um Tests durchzuführen...

Grüße

Namenloser 26. Aug 2013 22:31

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1226204)
Nur in den alten Pascal-Units (wie System.pas) ist ja an sich mindestens 90% eben nicht objektorientiert, sondern nur alleine rumbaumelnde Funktionen. Ob der Linker das auch kann?

Wenn eine Funktion nicht benutzt wird, landet sie auch nicht in der Exe. Zumindest wenn man vom Quellcode kompiliert, bei DCUs bin ich mir nicht ganz sicher.

Ansonsten, ich habe gerade mal nachgeschaut, meine einfachsten mit Delphi 2006 kompilierten Programme (also schon etwas mehr als eine leere Anwendung) sind in der Regel so 500 – 600kb groß.

Was unter neueren Delphis die Kompilate so aufbläht, ist wohl vor allem die erweiterte RTTI.

Furtbichler 26. Aug 2013 22:38

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Ach macht doch wat ihr wollt :mrgreen:

jaenicke 27. Aug 2013 05:10

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Zitat:

Zitat von Lemmy (Beitrag 1226322)
Interfaces bieten hier die Möglichkeit einen deutlich lockeren Verbund zu erstellen. Durch die Maßgabe gegen das Interface zu implementieren und nicht gegen eine Implementierung kann ich die Implementierung auch jederzeit austauschen, z.B. um Tests durchzuführen...

Klar, die Vorteile von Interfaces gibt es, aber solange man Interfaces nicht in die gleiche Datei packt, hat man das gleiche Problem. Bei Interfaces kommt deshalb das gleiche Schema in Frage.

Ich selbst habe das bisher eigentlich immer ohne Kreuzreferenz lösen können.

Zitat:

Zitat von Der schöne Günther (Beitrag 1226319)
Moment. Ich dachte, das sei nur ein Tippfehler und soll heißen
Delphi-Quellcode:
TCustomDogOwner = class(TDogOwner)
?

Schau mal in den VCL Quelltexten noch einmal. ;-)
Custom ist die Basis für konkrete Ableitungen, die dann nicht mehr das Custom drin haben. Zum Beispiel:
Delphi-Quellcode:
  TCustomEdit = class(TWinControl)
  TCustomMemo = class(TCustomEdit)

  TEdit = class(TCustomEdit)
  TMemo = class(TCustomMemo)

JamesTKirk 27. Aug 2013 05:33

AW: Class Helper als Lösung für zirkuläre Unit-Referenzen
 
Zitat:

Zitat von NamenLozer (Beitrag 1226329)
Zitat:

Zitat von Der schöne Günther (Beitrag 1226204)
Nur in den alten Pascal-Units (wie System.pas) ist ja an sich mindestens 90% eben nicht objektorientiert, sondern nur alleine rumbaumelnde Funktionen. Ob der Linker das auch kann?

Wenn eine Funktion nicht benutzt wird, landet sie auch nicht in der Exe. Zumindest wenn man vom Quellcode kompiliert, bei DCUs bin ich mir nicht ganz sicher.

Ja, funktioniert auch bei DCUs. Hatte schon oft, dass in unserem vorkompiliertem Code Funktionen keine blauen Punkte hatten und ergo nicht Bestandteil der Executable waren. Nennt sich übrigens Smartlinking das Verfahren.

Gruß,
Sven


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:02 Uhr.
Seite 3 von 4     123 4      

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