Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zyklusproblem ( Circular reference ) [solved] (https://www.delphipraxis.net/90727-zyklusproblem-circular-reference-%5Bsolved%5D.html)

DGL-luke 23. Apr 2007 16:54

Re: Zyklusproblem ( Circular reference )
 
Hallo,

ich würd das eher so machen, dass entweder du der INI-Unit deine TForm-Instanz übergibt und die macht dann was damit. Viel besser wärs aber - imo - dass die form auf die ini-unit zugreift, die ini/settings-klasse erstellt und sich dann selbst manipuliert.

Ich weiß nicht, warum das bis jetzt noch niemand erwähnt hat, aber wenn zwei Units aufeinander zugreifen müssen, hast du meistens irgendwo einen Designfehler bzw. "unsauberes" Design.

DGS 23. Apr 2007 17:00

Re: Zyklusproblem ( Circular reference )
 
Hi!

Zitat:

Zitat von DGL-luke
Viel besser wärs aber - imo - dass die form auf die ini-unit zugreift, die ini/settings-klasse erstellt und sich dann selbst manipuliert.

Aber dadurch würe die INI-Unit Sinnlos.
Wenn man tIniFiles einbindet, kommt man mit einer Funktion pro Lesevorgang aus.
Also kann man dann gleich alles in der HauptUnit behalten. Das führt aber dazu, dass die HauptUnit ( die, mit der Form) sehr stark anwächst.

Dass Zyklen ein Anzeichen für Designfehler ist, hab ich gelesen. Deshalb bin ich auch nach der Suche einer guten Alternative, um den Code effektiv auf mehrere Units aufzuteilen, besonders um die HauptUnit zu entlasten und halt gleichzeitig die Zyklen zu vermeiden. Hab gehofft, dass beides geht. Scheint mir aber eher so, dass man ohne kompromiss nicht weiterkommt.

trotzdem Danke für die Hilfe :)

DGL-luke 23. Apr 2007 17:05

Re: Zyklusproblem ( Circular reference )
 
dann halt so:

Delphi-Quellcode:
procedure LoadCommonFormSettings(Form: TForm; Filename: string);
begin
...
end;

DGS 23. Apr 2007 17:14

Re: Zyklusproblem ( Circular reference )
 
Also entweder übergebe ich dabei einen record von anderen Komponenten ( zB Checkobox, Labels ) oder ich lande wieder beim Zyklus.


Unit1 braucht die HelpUnit bei den Uses, um die Funktion aufzurufen.

Hier hat man die Wahl, ob man die Form1 sozusagen kopiert, und die Objekte auf der Form1 einzeln übergibt, oder sich entscheidet es sauberer zu gestallten und die Form1 übergibt. Ich hätte Form1 bevorzugt, weil so weniger redundante Angaben kommen. Aufwand wäre höher, um da eine neue Komponente zu ergänzen.

Apollonius 23. Apr 2007 17:19

Re: Zyklusproblem ( Circular reference )
 
Wenn du Funktionen aufrufst, dann brauchst du die unit nur in der implementation, da man Funktionen nur in der implementation aufrufen kannst.
Units brauchst du nur im interface-Teil in der uses, wenn du im Interface in einer anderen Unit deklarierte Typen verwendest. Für Funktionen nicht.
Es würde die Beantwortung deiner Fragen erheblich vereinfachen, wenn du dich etwas deutlicher ausdrücken würdest.

DGS 23. Apr 2007 17:40

Re: Zyklusproblem ( Circular reference )
 
Also eigentlich hab ich da weitestgehend keine Fragen. Dein letzter Hinweis (@Apollonius) hat mich eigentlich schon auf die gewünschte Lösung gebracht.

Mir geht es jetzt darum, ob ein "Zyklus", der durch implementation entschärft wurde, als unschönes Design zählt. Oder spricht man vom Designfehler, wenn der Zyklus rein auf der Interface Ebene stattfindet?

und wegen dem vorherigem Beitrag:
In der LoadCommonFormSettings(Form: TForm; Filename: string) müsste ich ein (Form as tForm1) machen müssen. Dann brauch ich unter uses (implementation) die Unit1.
Oder ich übergebe da alle Komponenten, die verändert werden können. Dann hätte ich aber viele Parameter und wäre dadurch fehleranfällig.


So, ich füg mal beim Titel ein [solved] hinzu.
gelöst als:

Delphi-Quellcode:
unit SubUnit;

interface

type
  tMyHelp = class
  private

  public
    constructor Create;
    procedure Einlesen(ini : TIniFile);
  end;

implementation

uses
  Unit1;

constructor tMyHelp.Create(image : tMyImage);
begin
  inherited Create;
end;

procedure tMyHelp.Einlesen(ini : TIniFiles);
begin
  Form1.checkbox1.checked := ini.readBool('A','B', true);
  // Form1 ist Variable in Unit1. Die wird durch uses "importiert"
end;
Das reicht mir jedenfalls erstmal und ich komm wieder gut weiter :)
Hatte das mit der Variable "Form1" vergessen gehabt.

Jelly 23. Apr 2007 19:42

Re: Zyklusproblem ( Circular reference )
 
Zitat:

Zitat von DGS
Und glaub, ich weis jetzt, was du meintest. In der Unit1. wird ja eine globale Variable Form1 deklariert.
*auf Kopf klatsch*
Dann reicht ja Unit1 in implementation aus und greif auf diese Variable zu.

Darf ich nochmal nachschlagen, damit's wenigstens bischen weh tut :angel2:

Hast du nicht in deinem ersten Beitrag was von OO Programmierung geschrieben :gruebel:
Dann solltest du aber wissen, dass man nicht unbedingt auf Instanzen direkt zugreifen soll. Was, wenn du plötzlich 2 Forms vom Typ TForm1 offen hast. Zugegeben, das ist in dem Beispiel eher unwahrscheinlich. Aber TForm1 könnte ja auch eine andere Klasse sein, von der du unterschiedliche Instanzen erzeugst.
In Unit2 (bzw. in TForm2 oder was auch immer) willst du auf Eigenschaften und Methoden von TForm1 zugreifen. Also übergib gefälligst eine Instanz von TForm1 im Konstruktor von TForm2.
Ich hoff, du verstehst was ich schreibe.

Und um deinem zirkulärem Problem aus dem Weg zu gehen, deklariere den constructor von TForm2 so:

Delphi-Quellcode:
unit SubUnit;

interface

uses
  forms;

type
  tHelp = class
  private
    fvater       : tForm;
  public
    constructor Create(vater : TForm)
  end;

implementation
uses unit1 ;

constructor tHelp.Create(vater : TForm);
begin
  assert ( vater is TForm, 'Parameter Vater con tHel.Create muss vom Type TForm1 sein.') ;
  inherited Create;

  fVater := vater;

  // irgendwas mit fVater machen
  with fVater as TForm1 do begin
  // ...
  end ;
end;

end.

DGS 23. Apr 2007 19:51

Re: Zyklusproblem ( Circular reference )
 
Zitat:

Zitat von Jelly
Darf ich nochmal nachschlagen, damit's wenigstens bischen weh tut :angel2:

Ja, bitte ;)

Hab jetzt den Code angeschaut und ... ja, so würde das auch funktionieren. Mir wird da nur etwas unwohl, wenn ich ständig (vater as tForm1) benutzen muss.

Aber es ist das, was ich von anfang an eigentlich erreichen wollte: Einen echten Verweis auf meine aufrufende Form1.

Wenn man aber den vater nicht im interface sondern in implementation abspeichert, kann man es auch als tForm1 abspeichern, richtig?

Zitat:

Zitat von Jelly
Hast du nicht in deinem ersten Beitrag was von OO Programmierung geschrieben :gruebel:

Vorher war das Programm streng prozedural aufgebaut. Keine Objekte.
Die neue Version hat dadurch nen >positive unendlichkeit< grösseren OO Anteil.
Auch wird nie vollstänige OOP angewandt. Einzig Gewichtung wird geändert.

Jelly 23. Apr 2007 21:19

Re: Zyklusproblem ( Circular reference )
 
Zitat:

Zitat von DGS
Wenn man aber den vater nicht im interface sondern in implementation abspeichert, kann man es auch als tForm1 abspeichern, richtig?

Möööp. Dann liegt die Variable aber nicht mehr in deiner THelp Klasse, und du kannst somit keine 2 THelp Instanzen erzeugen. Folglich gehört vater in die Klassendefinition rein.

DGS 24. Apr 2007 15:06

Re: Zyklusproblem ( Circular reference ) [solved]
 
stimmt.

Bin halt noch ned so gut Vertraut mit dem Thema OOProgrammierung.
Aber: Jeder muss mal klein anfangen :)

Die Frage ist, ob man von anfang an es lieber "richtig" macht, oder ob man sich auf ein Kompromiss einlässt und sich auf das beschränkt, was nötig ist. In meinem Fall brauch ich zB der Form1 nur eine einzige Instanz. Demnach würde mir die Variable Form1 aus der Unit1 vollkommen ausreichen.

Werde mir jedenfalls dein Beispiel noch abspeichern und für später aufheben :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:41 Uhr.
Seite 2 von 2     12   

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