![]() |
überkreuzender Bezug von Units .. kleiner Workaround
Habe eine recht schöne Lösung gefunden, wie man trotz nicht gestattetem überkreuzenden Bezug von zwei Units, diese Geschichte schön umgehen kann, ohne ständig Casts durchzuführen ...
Ziel. Zwei klassen brauchen im Klassenmodell eine gegenseitige Referenz aufeinander, befinden sich aber in verschiedenen Units.. in anderen Sprachen ja nicht so das Problem, in delpi aber nicht möglich.....
Delphi-Quellcode:
TClassA = class(TObject)
linkClassB : TClassB; end; TClassB = class(TObject) linkClassA : TClassA; end; Lösung ...
Delphi-Quellcode:
man speichert in _linkClassA die Referenz ab ... und greift nur noch über properties einer ClassHelper Klasse auf diese Referenz zu..
TClassA = class(TObject)
linkClassB : TClassB; end; TClassB = class(TObject) _linkClassA : TObject; end; diese befindet sich aber NUR im Implementationteil der Unit, damit ist ein quasi überkreuzender Bezug von Units möglich..
Delphi-Quellcode:
implementation
uses UnitClassA; type TConvertHelper = class helper for TClassB private function Get_linkClassA: TClassA; procedure Set_LinkClassA(const Value: TClassA); published property LinkClassA : TClassA read Get_LinkClassA write Set_LinkClassA; end; //============================================================================== function TConvertHelper.Get_LinkClassA: TClassA; begin result := TClassA(_linkClassA); end; //============================================================================== procedure TConvertHelper.Set_LinkClassA(const Value: TClassA); begin _linkClassA := Value; end; und jetzt kann man in irgendeiner Methode von TClassB wunderschön mit
Delphi-Quellcode:
auf das Object zugreifen, ohne ständig rumcasten zu müssen :-)
self.linkClassA
|
Re: überkreuzender Bezug von Units .. kleiner Workaround
Ok und in welcher Delphiversion funktioniert das?
|
Re: überkreuzender Bezug von Units .. kleiner Workaround
Hallo
![]() also Delphi.Net: D2005/2006 (?) aufwärts. Heiko |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Also in kleineren Versionen, überprüfe ich mit "is" bei "write property" ob es die korrekte Klasse ist.
Delphi-Quellcode:
Ich weiß jedoch nicht, ob es auch für abgeleitete Klassen funktioniert. Ich könnte mir es aber vorstellen.
property Xy : TObject read GetXy write SetXy;
procedure ...SetXy(Xy : TObject); begin if not (Xy is TMyClass) then raise .... end; |
Re: überkreuzender Bezug von Units .. kleiner Workaround
also sowohl in .NET als auch unter Win32 funktioniert das.
Ab Delphi 2005 |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
Zitat:
Im Ernst : glaube nicht, dass ich solch ein Konstrukt in zig-Programmen verwenden MUSS. Es gibt keins. 8) |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
|
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
Äh?
Delphi-Quellcode:
Oder hab ich was verpasst? :gruebel:
Type
TClassA = Class; TClassB = Class; ... TClassA = Class fRefB : TClassB; End; TClassB = Class fRefA : TClassA; End; |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
Zitat:
Uli. |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Ah. Na dann ... Ist die Aufteilung in Units falsch. Beide Klassen gehören, da untrennbar miteinander verbunden, auch zusammen.
|
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
|
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
|
Re: überkreuzender Bezug von Units .. kleiner Workaround
Dann löse dieses Dilemma mit Events. So ein Frame muss doch nicht wissen, das es auf einer TFoobarForm ist. Wozu dann ein Frame? Der Sinn eines Frames ist doch, das man es wieder verwenden kann. Aber so sind die beiden Klassen wirklich untrennbar verbunden.
Es ist doch bestimmt so, das dein Hauptformular irgendetwas machen muss, wenn sich im Frame Daten ändern. Und Du veränderst die Daten der Hauptform im Code/Kontext des Frames. Es ist praktischer, wenn das Frame seinem Eigentümer (oder wer auch immer das wissen will), Bescheid gibt, wenn sich etwas ändert. Dann kann der Eigentümer angemessen darauf reagieren, das Frame muss gar nichts über ihn wissen und alle (vor allen Dingen die OOP-Gemeinde) sind zufrieden. Du kannst das dann sehr leicht mit Events lösen: Spendiere dem Frame ein Event 'OnDataChanged' mit einem Parameter, der besagt, WAS geändert wurde, etwa so:
Delphi-Quellcode:
Und dann weist Du jedem OnChange-Event deiner Eingabefelder auf dem Frame diese Methode zu:
Type
TDataOnFrameChangedEvent = Procedure (Sender : TObject; aControl : TControl);
Delphi-Quellcode:
In Deinem Hauptformular erzeugst Du dir so eine Methode, implementierst *dort* die vorzunehmenden Aktionen und weist im FormCreate dem Frame-Ereignis diese Methode zu:
Procedure TMyFrame.DataOnFrameChanged (Sender : TObject);
Begin If Assigned (fDataOnFrameChanged) And (Sender Is TControl) Then fDataOnFrameChangedEvent (Self, TControl (Sender)); End;
Delphi-Quellcode:
Wenn sich im Frame nun etwas ändert, wird immer die Methode 'ReactOnDataChanged' über den Event-Mechanismus aufgerufen.
Procedure TMyMainForm.ReactOnDataChanged (Sender : TObject; aControl : TControl);
Begin If Sender = frmMyFrame Then If aControl = frmMyFrame.edVorname Then ShowMEssage(Format ('Der Vorname wurde in %s geändert',[TEdit (aControl).Text])); End; Procedure TMyMainForm.FormCreate (Sender : TObject); Begin ... frmMyFrame.OnDataOnFrameChangted := ReactOnDataChanged End; Ich finde diese Lösung auch deswegen besser, weil alle Aktionen, die Du im Hauptformulat in Abhängigkeit des Frames ausführst, in der Methode 'ReactOnDataChanged' konzentriert und an einer Stelle implementiert sind. Das ist übersichtlich und einfacher wartbar. |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
FTR: Meine Frames implementieren mittlerweile ein Interface, über das die Form ihre Funktionalität aufruft. Das Interface ist aber zu "ad hoc" für meinen Geschmack aufgebaut - riecht ziemlich nach Workaround. Andererseits: es funktioniert. :) |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
Aber ich werde mir deine Überlegungen mal genauer zu Gemüte führen, wenn mal etwas mehr Zeit ist. Vielleicht finde ich wirklich noch ein paar bessere "Sollbruchstellen" zwischen Form und Frame. Und vielen Dank für deine Ideen! Uli. |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
da stimme ich Dir zu. Aber es bleiben eben 10 Prozent übrig :) Und für diese 10 Prozent soll es ja auch eine Lösung geben. Auch ich bin der Meinung dass ein hirarchiches Klassenmodell besser ist. Eine Klasse kann eine andere Klasse als Eigentümer haben und zurück gehts per Events. Sehr richtig. Und ich muss Dir auch Recht geben, dass solche eng verknüpften Klassen dann auch in eine Unit gehören. Ich arbeite aber effektiver, wenn ich micht nicht durch ellenlange Units durcharbeiten muss. Auf zwei kleinere Units verteilt ist das für mich übersichtlicher. Aber das ist eine perönliche Meinung. Wenn Du magst, können wir ja gern mal über mein Klassenmodell diskutieren, ich bin sehr lernbereit! Aber ob Hochwürden auch so gnädig ist? Und was hast Du gegen Billiard? verlierst wohl immer? *g* beste Grüße |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
Er hat bis heute nicht kapiert warum es abstrakte Methoden gibt, du kannst ihn also in fachlichen Dingen komplett ignorieren. Manchmal wünschte ich, er könnte kurzzeitig verstehen worum es geht, so dass er sich grün & blau ärgern kann. (Über den Unsinn, den er so schreibt...) |
Re: überkreuzender Bezug von Units .. kleiner Workaround
@Elvis : wo bleiben denn deine theoretischen Theorien, die die Welt nicht braucht ? :lol: Ich meine die völlig abstrakten, die keiner benutzt und du keinen Widerspruch zu befürchten hast ? Echt lächerlich abstrakt. :mrgreen:
Stoxx, schildere mal das konkrete Problem. "Überkreuz" das riecht schon ziemlich nach Spaghetti-Code. |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
|
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
Zitat:
ich möchte mich aber jetzt nicht weiter in Eure Familienangelegenheiten einmischen, da tun sich ja Abgründe auf. Aber eigentlich magt ihr Euch doch, trinkt doch mal ein Bier zusammen. Aber gerade abstracte Methoden nehmen Dir doch die Schreibarbeit von case Anweisungen ab. Und genau das ist doch der Knackpunkt. Bei Quelltexterweiterungen an so wenigen Stellen wie möglich im Quelltext was ändern zu müssen. (Quelltextsicherheit) -> abstrakte Methoden ... Und ich verwende abstrakte Methoden auch durchaus. |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Abstraktion ist auch ein Grundprinzip der OOP
|
Re: überkreuzender Bezug von Units .. kleiner Workaround
ICh habe auch so ein "überkreuzender Bezug"-Problem:
Delphi-Quellcode:
Im Moment verwende ich folgende Deklaration:
unit Descriptor;
uses Token,...; TSecurityDescriptor = Class(TObject) ... {@Name combines a parent and a creator security descriptor into a new security descriptor. For detailed information see MSDN [url]http://msdn2.microsoft.com/en-us/library/aa446581.aspx[/url] @param(ObjectType A Pointer to a GUID that defines the type. Set to nil if it does not exist.) @param(GenericMap Defines the generic map class which maps generic access rights to specific access rights.) @param(Token defines the token instance which is used to check for access. Can be nil to use process or thread token.) } constructor CreatePrivateObjectSecurity( const ParentSecurityDescriptor: TJwSecurityDescriptor; const CreatorSecurityDescriptor: TJwSecurityDescriptor; const ObjectType : PGUID; const IsDirectoryObject : Boolean; const AutoInheritFlags : Cardinal; const GenericMap : TJwSecurityGenericMappingClass; const Token : TSecurityToken = nil); //Fehler ... end. unit ...Token; uses Descriptor,...; TSecurityToken = Class(TObject) ... {Sicherheitsdeskriptor für das Token} property SecurityDescriptor : TSecurityDescriptor read GetSecurityDescriptor write SetSecurityDescriptor; ...
Delphi-Quellcode:
Dabei wird Token auf den Typ überprüft :
constructor CreatePrivateObjectSecurity(
const ParentSecurityDescriptor: TJwSecurityDescriptor; const CreatorSecurityDescriptor: TJwSecurityDescriptor; const ObjectType : PGUID; const IsDirectoryObject : Boolean; const AutoInheritFlags : Cardinal; const GenericMap : TJwSecurityGenericMappingClass; const Token : TObject = nil); //Ok
Delphi-Quellcode:
Was könnte man da Vernünftiges machen?
if not (Token is TSecurityToken) then
raise |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
Ein TButton kommuniziert ja auch nur über Events wie OnClick zum Formular zurück und nicht mit dem direkten Aufruf eines Formulars, auf dem es sich befindet..... Und deswegen lässt er sich ja so universell verwenden :-) Deine Tokenklasse ist wahrscheinlich auch universell? Ansonsten, das Prinzip mit der ClassHelper Lösung nicht verstanden? .. hmmm |
Re: überkreuzender Bezug von Units .. kleiner Workaround
Zitat:
Und wie soll denn hier ein Event funktionieren? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:45 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-2025 by Thomas Breitkreuz