AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Class Helper als Lösung für zirkuläre Unit-Referenzen
Thema durchsuchen
Ansicht
Themen-Optionen

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

Offene Frage von "jaenicke"
Ein Thema von Der schöne Günther · begonnen am 25. Aug 2013 · letzter Beitrag vom 27. Aug 2013
Antwort Antwort
Seite 1 von 2  1 2      
Furtbichler
(Gast)

n/a Beiträge
 
#1

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

  Alt 26. Aug 2013, 07:27
Diese Lösung mit dem Zeiger-In-Den-Nebel (TObject) ist doch -ehrlich gesagt- Quark. Innerhalb von THund kannst Du ja gar nicht auf den Hundebesitzer zugreifen. Somit ist diese Umschiffung (eine Lösung ist das ja nicht) des Henne-Ei-Problems mittels Classhelper vielleicht ein Notbehelf, aber imho ein ziemlich einengender.

Das Problem tritt ja dann auf, wenn man eine eigentlich saubere Implementierung in unterschiedliche Units aufteilt. Wären sie in einer Unit, gäbe es das Problem nicht:
Delphi-Quellcode:
Type
  THundebesitzer = class;
  THund = class
     fHundebesitzer : THundebesitzer;
  public
     Hundebesitzer : THundebesitzer read ....;
  End;
Wieso verwendest Du nicht einfach Interfaces? Wenn man das konsequent durchzieht und keine kranken Sperenzien anstellt, gibt es auch keine Probleme.

Geändert von Furtbichler (26. Aug 2013 um 07:31 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.071 Beiträge
 
Delphi 10.4 Sydney
 
#2

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

  Alt 26. Aug 2013, 08:14
Und was ist mit der Möglichkeit, in einer dritten Unit ein generisches Dictionary anzulegen, was die Zuordnung von Hund und Hundehalter speichert?
Außerdem könnte so ein Hundebesitzer leicht mehrere Hunde haben oder umgekehrt ein Hund zwei Besitzer (Herr und Frau Müller).
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#3

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

  Alt 26. Aug 2013, 08:17
Und was ist mit der Möglichkeit, in einer dritten Unit ein generisches Dictionary anzulegen, was die Zuordnung von Hund und Hundehalter speichert?
Außerdem könnte so ein Hundebesitzer leicht mehrere Hunde haben oder umgekehrt ein Hund zwei Besitzer (Herr und Frau Müller).
Hier geht es nicht um Design, sondern um die Lösung eines allgegenwärtigen Problems: Zirkuläre Referenzen. In diesem Fall *soll* es ja so sein, das ein Hund maximal einen Besitzer hat. Das ist sozusagen Constraint-By-Design. Bei deiner Lösung müsste man das in der Dictionary-Klasse explizit ausprogrammieren.

Tendentiell ist so eine Relationsklasse natürlich ein schöner Ansatz, wenn die Besitzverhältnisse mit Logik verbunden sind.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.869 Beiträge
 
Delphi 12 Athens
 
#4

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

  Alt 26. Aug 2013, 08:46
In den meisten Fällen lässt sich das auch viel einfacher durch eine saubere Schnittstelle lösen. Denn die Frage ist doch was man von dem Objekt Hund im Objekt Besitzer machen will. Meistens kann man das auch über Events oder ähnliches lösen.
Delphi-Quellcode:
// Zum Beispiel nicht:
Hund.Bellen;
Hund.Besitzer.Schimpfen;

// sondern:
Hund.OnBellt := Besitzer.HundBelltEvent;

procedure TBesitzer.HundBelltEvent;
begin
  Schimpfen;
end;

// und dann nur:
Hund.Bellen;
// EDIT:
Interfaces lösen das Problem auch nicht, wenn man tatsächlich eine echte Referenz in beide Richtungen will. Man könnte allerdings die Referenz in einem abgeleiteten Interface unterbringen und nur das Basisinterface zurück referenzieren. Das geht bei Klassen aber auch.
Sebastian Jänicke
AppCentral

Geändert von jaenicke (26. Aug 2013 um 08:49 Uhr)
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.388 Beiträge
 
Delphi 10.4 Sydney
 
#5

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

  Alt 26. Aug 2013, 09:24
// EDIT:
Interfaces lösen das Problem auch nicht, wenn man tatsächlich eine echte Referenz in beide Richtungen will. Man könnte allerdings die Referenz in einem abgeleiteten Interface unterbringen und nur das Basisinterface zurück referenzieren. Das geht bei Klassen aber auch.
natürlich lösen die Interfaces das Problem. Zumindest wenn man Interfaces wie Interfaces verwendet und nicht wie KLassen

Grüße
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.869 Beiträge
 
Delphi 12 Athens
 
#6

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

  Alt 26. Aug 2013, 11:21
natürlich lösen die Interfaces das Problem. Zumindest wenn man Interfaces wie Interfaces verwendet und nicht wie KLassen
Sofern du zwei Interfaces hast und die Referenz jeweils auf das andere drin hast, geht das auch nicht. Wenn du ein Basisinterface auf einer der beiden Seiten referenzierst, geht das, aber das geht auch bei Klassen.

Und wenn du ein zusätzliches Interface benutzt, musst du erst dieses zusätzliche Interface nehmen, ggf. mit as drauf casten z.B., das ist auch nicht so schön. Aber es kommt halt drauf an was man genau braucht.

Wenn man die benötigten Funktionen der Besitzerklasse in eine Klasse TCustomBesitzer packt und die Klasse Hund erst in TBesitzer aus einer anderen Unit referenziert, funktioniert es jedenfalls auch.

Die beste Lösung ist aber Kreuzreferenzen zu vermeiden und nicht diese durch Interfaces oder ähnliches zu forcieren, wobei man bei Interfaces dann auch noch aufpassen muss, dass man keine Kreise einbaut, so dass die Objekte nie freigegeben werden.
Dass das Vermeiden nicht immer geht, sieht man ja an den weak references im ARM Compiler für iOS, die genau so etwas dort erlauben.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#7

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

  Alt 26. Aug 2013, 13:51
Interfaces kann man in eine Unit schmeißen, Klassen sollte man -der besseren Übersicht halber- aufteilen. Wenn man das so macht, lösen Interfaces diese Probleme der zirkulären Referenz.

Klar, alles in eine Datei schmeißen geht auch, aber ich hatte da mal dann ca. 10.000 Zeilen in einer Datei und das ist irgendwie uncool.

Dann lieber 500 Zeilen Interfacegedöns in einer Datei und 50 Klassen in 50 separaten Dateien.

Wer das alles partout ausschließen will, bricht sich eben einen ab (z.B. mit anonymen Verweisen, irgendwelchen Drittklassen, die die Beziehung verwalten usw. usw.)

Ich denk dabei immer an KISS. Und zwar so S wie möglich, also KIASAPDABWGU ("keep it as simple as possible, dumb ass, but without getting unübersichtlich"). Oder so ähnlich jedenfalls.

Und wichtig ist: Die Prämisse (KISS+Zusätze) ist am Wichtigsten. Wer meint, eine Datei reicht und ist KISS. Super. Wenn die Kollegen einverstanden sind => Cool. Genauso verhält es sich mit allen angebotenen Lösungen.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.191 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

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

  Alt 26. Aug 2013, 10:32
Innerhalb von THund kannst Du ja gar nicht auf den Hundebesitzer zugreifen. Somit ist diese Umschiffung (eine Lösung ist das ja nicht) des Henne-Ei-Problems mittels Classhelper vielleicht ein Notbehelf, aber imho ein ziemlich einengender.
Ich kann also innerhalb von THund auf den Besitzer entweder über das property direkt zugreifen oder über das ungecastete Objekt, wobei ich dann jedes Mal casten muss?
Das habe ich in dem Kurzbeispiel ausgelassen: Den gleichen Class Helper hätte ich jetzt in den implementation -Teil von Hund.pas gesetzt. Somit muss ich auch intern in THund den Zeiger in den Nebel nicht casten. Außerdem könnte ich diesen "internen" Helper ja noch um eine zweite Property (bzw. Getter-Methode) erweitern, die ein anderes Verhalten aufweist als die "normale" für "von außen". Auch wenn das jetzt nicht mein Fall wäre...


Denn die Frage ist doch was man von dem Objekt Hund im Objekt Besitzer machen will. Meistens kann man das auch über Events oder ähnliches lösen.
Guter Einwand! Das wird bestimmt zu oft übersehen (auch von mir).

Wieso verwendest Du nicht einfach Interfaces? Wenn man das konsequent durchzieht und keine kranken Sperenzien anstellt, gibt es auch keine Probleme.
Vielleicht ist es für mich noch zu früh am Morgen - Aber wo hilft mir das? Angenommen beide Klassen müssen sich gegenseitig kennen. Sie sind so unterschiedlich, ich finde keine sinnvolle Abstraktion die auf beide zutrifft. IHund muss nun eine Property vom Typ IHundesitzer nach außen führen und umgekehrt. Oder war das anders gedacht? Interface nur für einen von beiden (wie auch hier nur Helper-Klasse für einen)?

Außerdem hätte ich spontan Angst vor der automatischen Referenzzählung durch Interfaces - Mit der habe ich noch keine Erfahrung: Zwei Instanzen referenzieren sich nun gegenseitig, außerhalb davon hat die Welt allerdings bereits mit ihnen abgeschlossen. Nun trudeln die beiden auf ewig Hand in Hand durch meinen Speicher. Kennt Delphi etwas wie "Weak References"?

Ich packe Klassen, die sich gegenseitig benötigen, einfach in dieselbe Unit. So schlimm ist das gar nicht. Lange Units sind halt auch irgendwie der Pascal-Way... guckt euch doch nur mal die VCL an.
Wenn ich kleine Kinder in Angst und Schrecken versetzen will, tue ich das mit der System.pas: Knappe 40.000 Zeilen kann doch keiner mehr ernst meinen. Da braucht man sich dann auch nicht mehr zu wundern, wenn man für ein "Hallo Welt" schon 20 Megabyte braucht.

Geändert von Der schöne Günther (26. Aug 2013 um 10:35 Uhr)
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#9

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

  Alt 26. Aug 2013, 10:40
Da braucht man sich dann auch nicht mehr zu wundern, wenn man für ein "Hallo Welt" schon 20 Megabyte braucht.
Doch, eigentlich schon - das mit den Klassen hat der Linker ganz gut drauf - wenn Du 10 Klassen in einer Unit hast und nur eine verwendest, landet auch nur die in der EXE. Das allein ist kein Argument gegen mehrere Klassen in einer Unit.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.191 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

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

  Alt 26. Aug 2013, 10:47
Stimmt! Da hätte ich auch selber drauf kommen können, da der Linker mir immer gerne Klassen rausoptimiert hatte, die im Quelltext nicht direkt erwähnt, sondern nur indirekt über die RTTI gesucht wurden

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?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz