AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Trennung von GUI und Logik

Ein Thema von Maekkelrajter · begonnen am 28. Apr 2019 · letzter Beitrag vom 2. Mai 2019
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
847 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: Trennung von GUI und Logik

  Alt 29. Apr 2019, 12:44
Warum der Umweg über eine separate StringList mit Assign? Man kann der Datenklasse doch auch direkt das Memo (bzw. dessen Property Strings) übergeben.

Delphi-Quellcode:
type

  TData = class
    public
        procedure FillList(aStrings: tStrings);
  end;

  TForm2 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    aData: TData;
  public
    { Public-Deklarationen }
  end;



var
  Form2: TForm2;

implementation

{$R *.dfm}

{ TData }

procedure TData.FillList(aStrings: tStrings);
begin
    aStrings.Add('eins');
    aStrings.Add('zwei');
    aStrings.Add('drei');
    aStrings.Add('vier');
    aStrings.Add('fünf');
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
    aData := TData.Create;
    aData.FillList(Memo1.Lines);
end;
Funktioniert wunderbar, und man kann die Methode FillList auch für andere Zwecke nutzen, wenn man z.B. die Daten nicht in einem Memo haben will.

Für Fortschrittsanzeigen etc. könnte man z.B. mit Messages arbeiten (der Datenklasse übergibt man dann einmalig das Handle der MainForm, die die Nachrichten dann abarbeitet), oder man erstellt eigene Events mit passenden EventHandlern. Dann hat man im Code der Datenklasse regelmäßig etwas wie
Delphi-Quellcode:
if assigned(fOnProgress) then
    fOnProgress(param1, param2, param3, ...);
wobei fOnProgress eine Variable vom Typ Procedure( parameterliste ) of Object ist, die in der MainForm implementiert ist und entsprechend zugewiesen wird.
The angels have the phone box.
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.415 Beiträge
 
Delphi XE5 Professional
 
#12

AW: Trennung von GUI und Logik

  Alt 30. Apr 2019, 06:58
Na dann ergänze ich mal paar Ideen. Wirkt gerade alles sehr kompliziert.

Wo wir uns einige sind:
Die Logik darf das Oberfläche nicht kennen und muss somit auch ohne Funktionieren.
Die Oberfläche interessiert sich aber für neue und geänderte Daten, damit diese ggf. Dargestellt werden können.
Die Geschäftsobjekte sollte es nun an einer Stelle im Quelltext geben. "single point of truth"

Daher werfe ich mal eine DIY Lösung ein, welche mit Ereignissen arbeitet, welche die Logik zur Verfügung stellt.
Der klassischen Ansatz "Observer Pattern".
Vielleicht auch das "Publisher-Subscriber Pattern".

Siehe auch:
https://github.com/spinettaro/delphi-event-bus
https://www.danielespinetti.it/2017/...-and-mvvm.html
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#13

AW: Trennung von GUI und Logik

  Alt 30. Apr 2019, 10:20
Die Logik darf das Oberfläche nicht kennen und muss somit auch ohne Funktionieren.
"ohne" übersetz ich mal mit "beliebig (Minimal)".
Dazu dann eine dumme(?) Frage:
Gegeben sei eine Logik die mit Hilfe von Threads irgendwelche Daten bearbeitet.Innerhalb des Treads wird regelmäßig ein Postmessage mit dem aktuellen Stand der Bearbeitung abgesetzt.
Was passiert, wenn die GUI diese Messages nicht kennt?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.289 Beiträge
 
Delphi 12 Athens
 
#14

AW: Trennung von GUI und Logik

  Alt 30. Apr 2019, 10:32
Zitat:
Was passiert, wenn die GUI diese Messages nicht kennt?
Die Messages die der Thread (der in der Logik erzeugt wird) sendet, kommen in der Logik an. Die Logik macht ein Event draus, was die GUI versteht. Die Logik sollte dann auch der Puffer sein, wenn die Aktualisierungen zu schnell kommen und die GUI die einfach nicht darstellen kann. ...fertsch.
Zitat:
"ohne" übersetz ich mal mit "beliebig (Minimal)".
"ohne" heißt "ohne". Imho darf die Logik die GUI nicht kennen. Beispiel: Wenn in der Logik Daten verarbeitet werden und schon in der Logik "Rücksicht" auf die Darstellung genommen wird stellen sich mir die Nägel hoch...

Geändert von haentschman (30. Apr 2019 um 10:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#15

AW: Trennung von GUI und Logik

  Alt 30. Apr 2019, 11:06
Seitdem ich viel mit Angular und RxJS mache weiß ich die Eleganz des Observer-Patterns erst richtig zu schätzen. Allerdings ist dort die GUI auch threadsafe, da müsste man in Delphi halt etwas aufpassen, machbar ist das aber auch.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.815 Beiträge
 
Delphi 12 Athens
 
#16

AW: Trennung von GUI und Logik

  Alt 1. Mai 2019, 08:32
Na wunderbar! Danke für das Kommentar
Und ich denke auch das ich ein Memory Leak erzeuge, jedenfalls nach meinem bisherigem Verständnis. Das TStringList, nach meinem Verständnis, wird nicht (sauber) geleert. Vermutlich nur das DesktopFile. Meine bisherigen Bemühungen schlugen aber bisher Fehl. Aber dafür mache ich mal bei Gelegenheit einen eigenen Thread auf.

Danke! Wieder was gelernt! Tolles Forum.

MfG
Ob es wirklich ein memory Leak ist seht ihr nicht, wenn das grüne Licht an geht, sondern wenn ihr in die dpr des Projektes
als erste Anweisung nach dem begin das hier reinschreibt:

ShowMemoryLeaksOnSHutdown := true;

Dann Programm ausführen, die entsprechende Aktion aufrufen und Programm beenden. Kommt keine Meldungsbox beim Beeenden
gibt's kein leak, kommt eine ist eines vorhanden.
  Mit Zitat antworten Zitat
Maekkelrajter

Registriert seit: 8. Mär 2017
Ort: Köln
118 Beiträge
 
Delphi 11 Alexandria
 
#17

AW: Trennung von GUI und Logik

  Alt 1. Mai 2019, 15:17
Hallo,

seit ein paar Tagen bin ich nun dabei, die hier vorgeschlagenen Methoden der Kommunikation zwischen GUI und Logik auszuprobieren. Dabei wird für mich immer deutlicher, dass eine absolute Trennung garnicht möglich ist, wenn die Logik während der Abarbeitung des Auftrages, der vom GUI erteilt wurde, Informationen an das GUI übermitteln bzw. Aktionen des GUI auslösen soll. Die absolute Trennung funktioniert doch eigentlich nur, wenn ausschließlich der Rückgabewert einer Funktion ausgewertet werden soll.
Denn sowohl beim Absetzen von Windows-Messages als auch beim Feuern von Events muss die Logik doch wissen, wohin 'gezielt' werden soll, um eine bestimmte Aktion des GUI auszulösen. Wie soll das gehen, wenn Logik und GUI überhaupt nichts voneinander 'wissen'?
Hier meine Implementierung eines Update - Events, das tadellos funktioniert.

Die Deklaration in der Logik-Klasse sieht folgendermaßen aus:

Delphi-Quellcode:
type

TUpdateGUIEvent = procedure(Sender: TObject; index:Integer; s: string) of Object;


TGlExLogic = Class
  private
    FUpdateGUI : TUpdateGUIEvent;
    Procedure UpdateGUI(Index:Integer; s: string);
    [...]
  public
    property OnUpdateGUI: TUpdateGUIEvent read FUpdateGUI write FUpdateGUI;
End;
So wird das Event in der Logik-Klasse ausgelöst:

Delphi-Quellcode:
Procedure TGlExLogic.UpdateGUI(Index:Integer; s :string);
begin
  If Assigned(FUpdateGUI) then
  begin
     FUpdateGUI(Self, Index, s);
  end;
end;
Die Implementierung im GUI sieht dann so aus:

Delphi-Quellcode:

procedure TGL4Mainform.FormCreate(Sender: TObject);
begin
   GLMainLogic := TGlExLogic.create(self);
   GlMainLogic.OnUpdateGUI := UpDateGUI;
end;

Procedure TGL4Mainform.UpdateGUI(sender:TObject; Index:Integer; s :string);
begin
  case index of
     1: Memo1.Lines.Add(s);
     2: Memo2.Lines.Add(s);
     8: label8.caption := s;
      [...] usw.
  end;
end;
Die Logik muss doch z. B.wissen, welche Parameter mitgegeben werden müssen, um bei einem bestimmten Control der Mainform ein Update auszuführen?! Es ist dann aber auch nie auszuschließen, das bei Änderung des GUI das eine oder andere nicht mehr funktioniert.
Da wird man wohl notgedrungen Kompromisse machen und von der reinen Lehre der OOP abweichen müssen. Oder habe ich da irgendwas nicht verstanden?

Gruß LP

PS: Die oder Das GUI? Nach den geltenden Regeln heißt es doch im Deutschen das Interface? Oder doch nicht??

Geändert von Maekkelrajter ( 1. Mai 2019 um 15:50 Uhr)
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.754 Beiträge
 
Delphi 10.4 Sydney
 
#18

AW: Trennung von GUI und Logik

  Alt 1. Mai 2019, 17:02
.. die Oberfläche muss doch wissen, welches Element es updaten muss.
Das hat nicht zwingend etwas mit dem Wissen der Businesslogik zu tun.
Wie das Ergebnis zustande kam, welches die Oberfläche aktualisieren muss
darüber weiß die Oberfläche nichts.

Ich weiß nicht, ob es nicht vielleicht sinnvoller wäre ein Ereignis pro GUI Element
zu haben?

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#19

AW: Trennung von GUI und Logik

  Alt 1. Mai 2019, 17:11
Die Logikschicht muss oder gar darf von der Oberfläche nichts wissen. Im Übrigen kann es ihr ja auch egal sein, ob ein String jetzt in einem Label, einem Edit oder als ListBox-Item dargestellt wird. Sie stellt einfach nur Ereignisse zur Verfügung, an die sich die Darstellungsschicht einklinken kann oder auch nicht.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#20

AW: Trennung von GUI und Logik

  Alt 1. Mai 2019, 17:22
Zitat:
Was passiert, wenn die GUI diese Messages nicht kennt?
Die Messages die der Thread (der in der Logik erzeugt wird) sendet, kommen in der Logik an. Die Logik macht ein Event draus, was die GUI versteht. Die Logik sollte dann auch der Puffer sein, wenn die Aktualisierungen zu schnell kommen und die GUI die einfach nicht darstellen kann. ...fertsch.
Die Logikschicht muss oder gar darf von der Oberfläche nichts wissen. Im Übrigen kann es ihr ja auch egal sein, ob ein String jetzt in einem Label, einem Edit oder als ListBox-Item dargestellt wird. Sie stellt einfach nur Ereignisse zur Verfügung, an die sich die Darstellungsschicht einklinken kann oder auch nicht.

Muß die Logik sich darum kümmern was aus ihren Messages wird oder nicht?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 22:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz