![]() |
Klassen sollen sich gegenseitig kennen
Hallo,
ich habe in einer Unit zwei Klassen definiert, die sich gegenseitig kennen sollen. Im folgenden nur eine vereinfachte Ausgangsstellung bei der das Problem auftritt, das der Compiler meckert:
Delphi-Quellcode:
Wenn das über Units verteilt wäre, wäre das diese zirkuläre Referenz Geschichte, wo ich eine unit im interface und die andere im implementation Teil deklarieren müsste. Aber wieso hier, wo doch alles in einer Unit steht? Ist das weil der Compiler von oben nach unten vor geht? Gäbe es dann sowas wie die Vorwärtsdeklaration bei C auch für Klassen?
TKapitel=class
private Abs:TAbschnitt; //hier meckert der Compiler: Undefinierter Bezeichner TAbschnitt end; TAbschnitt=class private Kap:TKapitel; end; |
AW: Klassen sollen sich gegenseitig kennen
Delphi-Quellcode:
Quelle:
uses
Generics.Collections; type MyParent = Class; // This is a forward class definition MyChild = Class private ParentObect:MyParent; public End; MyParent = Class // The MyParent class is now defined public tlChildren:TList<MyChild>; end; implementation end. ![]() |
AW: Klassen sollen sich gegenseitig kennen
Cool. Ich hab sowas ja vermutet, aber das lief nicht. Mein Fehler war der selber wie im Stackoverflow-Thread: Ich hab mehr als ein Type benutzt. Danke, auch für den Link.
Witzigerweise ist meine Intention dieselbe, wie beim dortigen Thread-Ersteller nur umständlich mit TObjectList, da noch ohne Generics. |
AW: Klassen sollen sich gegenseitig kennen
Wie wärs mit
Delphi-Quellcode:
Nennt sich forward-declaration (Edit: oh das kennst du ja bereits)
TKapitel = class;
TAbschnitt = class; TKapitel=class private Abs:TAbschnitt; //hier meckert der Compiler: Undefinierter Bezeichner TAbschnitt end; TAbschnitt=class private Kap:TKapitel; end; |
AW: Klassen sollen sich gegenseitig kennen
Klassen, die sich gegenseitig kennen, sind i.A. (also nicht immer!) ein Indikator für schlechtes Design. Ich würde es mit einem Mediator-Pattern versuchen, der zwischen beiden Klassen vermittelt.
Geht das nicht, sind imho Interfaces die sauberere Alternative zu forward-Deklarationen. |
AW: Klassen sollen sich gegenseitig kennen
Keine Ahnung ob das in meinem Fall schlechtes Design ist oder eine der Ausnahmen. Meine Kapitel kennen "ihre" Abschnitte. Die Abschnitte müssen erstmal nicht wissen, in welchem Kapitel sie sind. Sie bräuchten also von daher TKapitel erstmal nicht kennen.
Es geht nun aber darum, das ein Abschnitt evtl. erst freigeschaltet wird wenn ein anderes Kapitel beendet wurde. Er muss somit nicht das Kapitel kennen in dem er steckt, also sein Elternobjekt, aber ein anderes Kapitel von dem er ggf. abhängig ist. Ich hab das Mediator-Pattern mal bei Wikipedia nachgeschaut und es scheint mir für den Fall zu aufwendig, aber da mir da die Erfahrung mangelt täusch ich mich vllt. auch. Man könnte natürlich noch eine weitere Zentrale Klasse erstellen, die entscheidet, wann ein Abschnitt freigegeben wird, die somit sämtliche dafür nötigen Informationen, Verknüpfungen verwaltet, aber das find ich zu aufwendig. "Ist doch einfacher die Klasse Abschnitt selber zu Fragen, ob sie freigegeben (nicht im Sinne von .Free!!!) ist, die wiederum ihr "Vorgänger"-Kapitel fragt, ob es schon durch ist." |
AW: Klassen sollen sich gegenseitig kennen
Gutes OOP geht nicht immer den Weg des schnellsten Umsetzens, sondern den Weg, was am einfachsten wartbar und erweiterbar ist.
Ich würde eine hierarchische Beziehung aufbauen, da dies den Daten entspricht. Der Mediator wäre dann dafür zuständig, bestimmte Eigenschaften in Abhängigkeit anderer Änderungen anzufassen. Das ist nicht aufwändig. Es wird nur diese eine Funktionalität in eine eigene Klasse verlagert. Ich würde mir die Mühe machen, das exemplarisch zu implementieren (sofern die Zeit es zulässt und der Chef nicht hinter einem steht). |
AW: Klassen sollen sich gegenseitig kennen
Zitat:
Zitat:
Delphi-Quellcode:
TBuchKnoten = class
// Gemeinsamkeiten von TKapitel und TAbschnitt hier rein ... end; TAbschnitt=class(BuchKnoten) private Parent:BuchKnoten; // Elternteil ist meist ein TKapitel (könnte aber auch TKlappentext sein) end; TKapitel=class(BuchKnoten) private Abschnitt : TAbschnitt; end; |
AW: Klassen sollen sich gegenseitig kennen
Zitat:
Gleichzeitig ist das für mich aber auch eine Übung auch mal komplexere Modelle umzusetzen, weswegen mir eure Anregungen schon sehr recht sind. sx2008s Vorschlag ist auch interessant, da ein Abschnitt sowohl von einem früheren Kapitel als auch einem früheren Abschnitt abhängig sein kann (bisher gelöst durch ein Feld für vorherigen Abschnitt und eines für vorheriges Kapitel). Mit dem Basis-Klassen-Gedanken, könnte ich natürlich stattdessen eine Liste vom Typ Basisklasse verwalten und da sowohl Kapitel als auch Abschnitt reinschieben und wäre später noch offen dafür, dass mal die Anforderung kommt von mehreren Kapiteln oder Abschnitten abhängig zu sein und dann brauch ich die Klasse nicht wieder umbauen. Gleichzeitig ist mir aber eben auch der Gedanke gekommen das andersherum aufzuziehen, sprich der Vorgänger-Abschnitt bzw. das Kapitel bekommt eine Liste von Nachfolgern, die es benachrichtigen soll, wenn sich sein Status (ungelesen->gelesen) ändert. Worauf diese dann ihren Status auf freigegeben ändern können. Ich muss da mal das WE drüber nachdenken. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01: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