Autor |
Beitrag |
LittleBen
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Do 17.10.13 20:50
Hallo,
in der Schule behandeln wir zurzeit das Thema 3-Schichtenmodell in Java, also GUI,Steuerung und Daten.
Jetzt meine Frage: ist das Java-Spezifisch oder handhabt man das in Delphi auch so? Hab meine Projekte bis jetzt immer komplett anders gestaltet...halte es aber für eine gute Idee.
Und noch eine frage: Wie löst man die Kommunikation zwischen den verschiedenen Schichten? Ich würde es, um den Code noch mehr zu verallgemeinern, alles mit Events machen. Also die GUI kennt die Steuerung, aber die Steuerung nicht die GUI. Die Steuerung löst nur Events aus, die beim Kreieren mitgehlieft wurden. Die GUI reagiert dann darauf. Wie löst man das professionel, nach der alten delphischen Art?
Viele Grüße
Littleben
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 17.10.13 21:46
Das macht man in Delphi ähnlich. Ob nun GUI, Steuerung und Daten die beste Aufteilung ist, sei dahingestellt, aber prinzipiell eine Abtrennung mindestens der GUI ist immer sinnvoll.
Ich halte in Delphi Interfaces für am sinnvollsten. Mit Events programmierst du dich eher tot. Mit Interfaces registrieren sich die einzelnen Teile gegenseitig und fertig.
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Do 17.10.13 22:10
Mhm, wie würde das mit den Interface dann in etwas aussehen?
Angenommen man macht die GUI und Steuerung in eine Klasse (nur zur Übersichtlichkeit):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| unit Unit1;
interface
uses
type TMyControl = class private procedure DownloadSomeData; public end;
type TMyGUI = class(TForm) private FMyControl: TMyControl; public end;
var GUI: TGUI;
implementation
{$R *.dfm}
end. |
Wie würdest du hier die Kommunikation gestalten, wenn die GUI die Methode DownloadSomeData aus dem MyControl-Objekt aufruft, und dieses dann die Daten auf die GUI schreiben soll (kein Thread, und auch keine Rückgabewert  ).
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 17.10.13 23:22
Ein vollständiges Beispiel, nicht sonderlich schön, aber es sollte das Prinzip zeigen: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73:
| program Project17;
uses Vcl.Forms, System.Generics.Collections, Unit9 in 'Unit9.pas' ;
{$R *.res}
type TAppController = class(TInterfacedObject, IAppController) private var FGUIList: TList<IMyGUI>; public constructor Create; destructor Destroy; override; procedure RegisterGUI(const AGUI: IMyGUI); procedure UnregisterGUI(const AGUI: IMyGUI); procedure DisplayText(const AValue: string); procedure TextEntered(const AValue: WideString); end;
constructor TAppController.Create; begin FGUIList := TList<IMyGUI>.Create; end;
destructor TAppController.Destroy; begin FGUIList.Free; inherited; end;
procedure TAppController.DisplayText(const AValue: string); var CurrentGUI: IMyGUI; begin for CurrentGUI in FGUIList do CurrentGUI.DisplayText(AValue); end;
procedure TAppController.RegisterGUI(const AGUI: IMyGUI); begin if not FGUIList.Contains(AGUI) then begin AGUI.RegisterController(Self); FGUIList.Add(AGUI); end; end;
procedure TAppController.TextEntered(const AValue: WideString); begin DisplayText(AValue); end;
procedure TAppController.UnregisterGUI(const AGUI: IMyGUI); begin FGUIList.Remove(AGUI); end;
var MyController: IAppController; begin MyController := TAppController.Create; Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm9, Form9); MyController.RegisterGUI(Form9); Application.Run; end. | 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60:
| unit Unit9;
interface
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type IMyGUI = interface;
IAppController = interface procedure TextEntered(const AValue: WideString); procedure RegisterGUI(const AGUI: IMyGUI); end;
IMyGUI = interface procedure RegisterController(const AController: IAppController); procedure DisplayText(const AValue: WideString); end;
TForm9 = class(TForm, IMyGUI) Memo1: TMemo; Memo2: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); private var FController: IAppController; protected procedure RegisterController(const AController: IAppController); procedure DisplayText(const AValue: WideString); end;
var Form9: TForm9;
implementation
{$R *.dfm}
procedure TForm9.Button1Click(Sender: TObject); begin if Assigned(FController) then FController.TextEntered(Memo2.Text); end;
procedure TForm9.DisplayText(const AValue: WideString); begin Memo1.Text := AValue; end;
procedure TForm9.RegisterController(const AController: IAppController); begin FController := AController; end;
end. |
In einem echten Programm gehören die Klassen und Interfaces natürlich in eigene Units usw., wie gesagt, nur ein ganz schnelles Beispiel...
Architektur:
Die GUI wird beim Controller angemeldet, der Controller meldet sich bei dieser Registrierung wiederum bei der GUI an. Dazu kann dann ebenso vom Controller aus noch der Datenteil kommen.
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Fr 18.10.13 16:03
Vielen Dank für das Beispiel!
Die Interfaces kommen dann in eine eigene Unit. Wie wird diese so standardmäßig genannt?
Delphi-Quelltext 1: 2:
| type IMyGUI = interface; | Ich nehme mal an, diese Zeile war ein Versehen?
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 18.10.13 16:15
LittleBen hat folgendes geschrieben : | Die Interfaces kommen dann in eine eigene Unit. Wie wird diese so standardmäßig genannt? |
Zum Beispiel kannst du das in einen Unterordner Interfaces legen und die Units genauso wie die Interfaces nennen. Also Zum Beispiel Littleben.Interfaces.MyGUI für das Interface IMyGUI. Wenn du es weniger modular haben möchtest, kannst du auch die Interfaces in einer eigenen Interface-Unit zusammen lassen, aber ich finde das etwas unübersichtlich.
Bei deinem Delphi 7 weiß ich nicht, ob die Punkte im Unitnamen überall funktionieren. Das konnte das zwar schon, aber ich weiß nicht, ob überall.
Ich würde jedenfalls entweder eine Sammelunits für die Interfaces oder Units, die mit Interfaces und ggf. einem Zusatz genauso wie das Interface heißen nehmen.
LittleBen hat folgendes geschrieben : | Delphi-Quelltext 1: 2:
| type IMyGUI = interface; | Ich nehme mal an, diese Zeile war ein Versehen? |
Nein, eine forward Deklaration. Das danach folgende Interface benötigt das Interface IMyGUI, deshalb muss vorher schon einmal deklariert werden was das für ein Typ ist, nämlich ein Interface.
In deinem echten Programm sollten solche Rückwärtsreferenzen nicht nötig sein, das lag nur daran, dass das Beispiel so kompakt bleiben sollte.
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Mi 23.10.13 19:26
Ich habe das gerade mal unter XE5 (bin jetzt auch auf dem neusten Stand  ) mit Firemonkey auspobiert. Dort bekomme ich eine Access Violation sobald ich das Formular vor Application.Run benutze.
Wie muss ich es dann anstellen?
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 23.10.13 19:34
Naja, erstellt sein muss es. Das Hauptformular mit Application.FormCreate, die anderen direkt. Ohne Quelltext kann man dazu aber nicht viel sagen.
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Mi 23.10.13 19:44
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 23.10.13 22:09
Das sieht erst einmal nicht schlecht aus. Häng am besten mal das ganze Projekt an, viel ist da ja vermutlich ohnehin noch nicht drin.
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Do 24.10.13 12:32
Okay, im Anhang mein Testprojekt. Muss ein saublöder Fehler sein
Wenn ich testweise soetwas einbau:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var Controller: IMyController; begin Controller:= TMyController.Create; Application.Initialize; Application.CreateForm(TF_Main, F_Main); Application.Run; Controller.RegisterGUI(F_Main); Application.ProcessMessages; Sleep(1000); |
dann funktioniert es, aber eben erst nach dem Schliesen...
EDIT: Hab das Problem gefunden gefunden... nach dem CreateForm muss noch folgendes eingefügt werden:
Application.RealCreateForms;
Dann funktionierts!
Einloggen, um Attachments anzusehen!
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 24.10.13 13:29
Ok, das ist nur mit FireMonkey so, in der VCL wird das Formular auch direkt erzeugt, nicht erst beim Ausführen.
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Do 24.10.13 15:19
So ein scheeeiii....
Unter iOS darf ich die Forms nicht früher kreieren. Ich bekomme bei der Funktion function TPlatformCocoaTouch.CreateWindow(const AForm: TCommonCustomForm): TWindowHandle; eine Access Violation Exception bei LOrientation := UIApp.statusBarOrientation;
Keine Ahnung was ich jetzt tun soll 
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 24.10.13 15:59
|
|
LittleBen 
      
Beiträge: 258
Erhaltene Danke: 4
Win 7, Mac OS
Delphi 7
|
Verfasst: Do 24.10.13 17:33
jaenicke hat mal wieder zugeschlagen
Funktioniert.
Nur noch aus Interesse: Gäbe es noch eine oder mehere Möglichkeiten das Proboblem zu lösen? Hörte sich so an als wüsstest du noch andere Wege.
|
|
|