AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Trennung von GUI und Logik

Ein Thema von Maekkelrajter · begonnen am 28. Apr 2019 · letzter Beitrag vom 2. Mai 2019
Antwort Antwort
Seite 1 von 2  1 2   
Neumann

Registriert seit: 6. Feb 2006
Ort: Moers
540 Beiträge
 
Delphi 12 Athens
 
#1

AW: Trennung von GUI und Logik

  Alt 28. Apr 2019, 16:49
Der 'Button1click' macht nur etwas mit der GUI. Den würde ich nicht woanders hin auslagern. Wenn man die Liste noch sonst noch braucht, könnte man diese als Stringlist z.B. in einem Datenmodul definieren.

So wie der Code aussieht, würde wohl nur das Endergebnis für den User sichtbar werden, die Zwischenergebnisse sieht man so wohl nicht.
Ralf
Gruß vom Niederrhein
  Mit Zitat antworten Zitat
Maekkelrajter

Registriert seit: 8. Mär 2017
Ort: Köln
157 Beiträge
 
Delphi 12 Athens
 
#2

AW: Trennung von GUI und Logik

  Alt 28. Apr 2019, 17:33
Der 'Button1click' macht nur etwas mit der GUI.
Das Beispiel soll nur das Problem verdeutlichen. In der tatsächlichen Implementierung umfasst der Code des Handlers 82 Zeilen, verwendet das iTunes COM-Interface und enthält 13 Zugriffe auf das GUI. Das macht vielleicht auch deutlich, warum das unbedingt geändert werden soll.

Der von Turbomagic skizzierte Weg scheint mir sehr vielversprechend. So etwas schwebte mir auch vor, nur hatte ich keinen Schimmer, wie das zu realisieren wäre. Interfaces kenne ich nur dem Namen nach, sie werden ja auch vom iTunes COM-Interface verwendet, aber da ist ja schon alles fertig in der iTunes Typelibrary vorhanden.

Gruß LP

Geändert von Maekkelrajter (28. Apr 2019 um 17:58 Uhr)
  Mit Zitat antworten Zitat
hum4n0id3

Registriert seit: 28. Sep 2018
5 Beiträge
 
#3

AW: Trennung von GUI und Logik

  Alt 29. Apr 2019, 07:24
Ich bin in Delphi/Lazarus selbst ein Anfänger, weil ich nur hin und wieder etwas damit mache. Hauptsächlich arbeite ich mit PHP und mache dort OOP. Deshalb vielleicht den "Ratschlag" nicht so ganz ernst nehmen. Aber ich mache es so.

1. Ich erstelle eine Unit mit Klasse-Name-XXX. Das enthält meist die Logik für meine Software. ZB.:

Delphi-Quellcode:
unit UDesktopFile;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil;

type
  TDesktopFile = class
    private

    public
      function GetAllFiles() : TStringList;

  end;

implementation

function TDesktopFile.GetAllFiles(): TStringList;
var
  StrList: TStringList;
  pathToFiles: String;
begin
  pathToFiles := GetUserDir + '/.local/share/applications/';
  StrList := TStringList.Create;

  FindAllFiles(StrList, pathToFiles, '*.desktop');
  GetAllFiles := StrList;
end;

end.
2. Ich verwende die Unit in meinem Hauptformular, oder einem anderem Formular, mit den Componenten im Formular.

Delphi-Quellcode:
procedure TFrmMainWindow.FormCreate(Sender: TObject);
var
  DesktopFile: TDesktopFile;
begin
  DesktopFile := TDesktopFile.Create;

  try
    LbDesktopFiles.Items.Assign(DesktopFile.GetAllFiles);
  finally
    DesktopFile.Free;
  end;

end;
Das ist jetzt kein Delphi, sondern Lazarus aber funktioniert für mich gut. Aber ob es so richtig ist und so gemacht wird, weiß ich nicht
Jedenfalls sind meine Formulare dadurch sauberer, bzw. übersichtlicher und für Änderungen muss ich die entsprechenden Units besuchen.

MfG
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

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

AW: Trennung von GUI und Logik

  Alt 29. Apr 2019, 08:48
Moin...
Ich bin für folgendes:

1. Trennung in die Form und die Logic (seperate Units)
2. Die Eventhandlandler gehören in die Form.
3. Die GUI Sachen gehören in die Form.
4. Die Logic kennt die Form nicht! ...auch kein Interface.
5. Die Form gibt im Eventhandler den "Befehl" an die Logic. "
6. Die Logic holt die Daten und übergibt sie an ein selbst erstelltes Event oder gibt die Daten an das Funktionsresult zurück.
7. Mit Event: Die Form hat den Eventhandler der Logic implementiert und übergibt die Daten an die GUI.
...fertsch.
PS: Der Kreativität sind keine Grenzen gesetzt.



constructor TBusinessLogic.Create(MainFormInterface: IMainFormInterface); Das mit dem Interface halte ich für gewagt. Wenn sich an dem GUI Interface was ändert, mußt du auch immer an die Logik dran...Das zu verhindern ist ja der Sinn der Trennung von GUI Und Logik.

PS: Ausnahmen bestätigen die Regel...

Geändert von haentschman (29. Apr 2019 um 08:50 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Trennung von GUI und Logik

  Alt 29. Apr 2019, 09:55
Hallo,

[B]class [/B]function GetAllFiles() : TStringList; Dann musst Du die Klasse im Formular nicht mal erstellen,
sondern per
LbDesktopFiles.Items.Assign([B]T[/B]DesktopFile.GetAllFiles); aufrufen.

Wobei ich mir nicht sicher bin,
ob die hier einen memory leak erzeugst.
Das Assign kopiert den Inhalt der TStringList.

Ich bin immer dafür, dass der der ein Objekt erzeugt,
auch für dessen Freigabe verantwortlich ist.
Das Formular würde also die StringList erzeugen, an die GetAllFiles als Parameter übergeben,
und wenn es die StringList nicht mehr braucht, wieder freigeben.
Heiko
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.739 Beiträge
 
Delphi 6 Enterprise
 
#6

AW: Trennung von GUI und Logik

  Alt 29. Apr 2019, 10:19
Das ganze Thema schreit für mich aber auch nach 'Threads'. Dementsprechend sollte vielleicht solche Dinge in eigene Threads ausgelagert werden, die dann auch nur periodisch die GUI aktualiesieren und nicht ständig.
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Trennung von GUI und Logik

  Alt 29. Apr 2019, 12:17
Man muss hier m.E. drei Dinge separat betrachten...


1) Trennung GUI/BL:

Dazu reicht es aus, sämtliche Logik in eine Klasse TMyBL zu stecken und dort so viele Eigenschaften und Methoden zu veröffentlichen, dass die GUI sich dort umfassend bedienen kann.
Die GUI darf also nie z.B. einen Kontostand erhöhen, indem sie den aktuellen Wert abruft, einen Betrag dazu rechnet und das Ergebnis wieder speichert, sondern sie muss TMyBL.AddMoney(x) aufrufen.
ALLES was an Daten zu ändern oder abzufragen ist, muss über Methoden und Eigenschaften möglich sein.
TMyBL muss also in sich das vollständige Projekt abbilden und komplett funktionsfähig sein.
Natürlich ist TMyBL hilflos ohne Ansteuerung von außen, aber alle Erfordernisse müssen dort vorhanden und nutzbar sein.
Die GUI (Egal ob VCL, FMX oder anderes) stößt dann lediglich Aktionen an und ruft Daten ab für die eigene Darstellung.

Wenn man mit Interfaces umgehen kann ist das sicherlich hilfreich, aber ein klassisches TMyBL-Objekt würde auch reichen.

Eine Trennung von GUI und BL wäre damit schon erreicht.


2) Threads:

Egal, ob eine längere Berechnung im Eventhandler des Formulars erfolgt oder in der oben beschriebenen TMyBL-Klasse, das Formular wird während dieser Zeit hängen bleiben.
Um das zu vermeiden, muss man mit Threads arbeiten oder notfalls mit Timern oder gar Application.ProcessMessages.
Hier ist zu beachten, dass die TMyBL davon nicht abhängig sein darf. Am besten sollte sie davon gar nichts mitbekommen.


3) Kommunikation

Vor allem, wenn GUI und BL in getrennten Threads oder gar Prozessen laufen, muss man sich über die Kommunikation Gedanken machen.
Die GUI darf die BL kennen und dort Änderungen anschieben aber sie sollte gar nicht wissen, was sie da eigentlich tut und warum.
Die BL sollte aber gar nichts von der GUI wissen.
Es muss aber einen abstrakten Informationsaustausch geben, also am besten über einen Framework, das zwischen beiden Seiten (möglichst automatisiert) vermittelt.
Die Frage ist, wie man das am besten organisiert (je nach Anspruch und Möglichkeiten).
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
hum4n0id3

Registriert seit: 28. Sep 2018
5 Beiträge
 
#8

AW: Trennung von GUI und Logik

  Alt 29. Apr 2019, 13:19
Hallo,

[B]class [/B]function GetAllFiles() : TStringList; Dann musst Du die Klasse im Formular nicht mal erstellen,
sondern per
LbDesktopFiles.Items.Assign([B]T[/B]DesktopFile.GetAllFiles); aufrufen.

Wobei ich mir nicht sicher bin,
ob die hier einen memory leak erzeugst.
Das Assign kopiert den Inhalt der TStringList.

Ich bin immer dafür, dass der der ein Objekt erzeugt,
auch für dessen Freigabe verantwortlich ist.
Das Formular würde also die StringList erzeugen, an die GetAllFiles als Parameter übergeben,
und wenn es die StringList nicht mehr braucht, wieder freigeben.
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
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

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

AW: Trennung von GUI und Logik

  Alt 29. Apr 2019, 13: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.
Being smart will count for nothing if you don't make the world better. You have to use your smarts to count for something, to serve life, not death.
  Mit Zitat antworten Zitat
TurboMagic

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

AW: Trennung von GUI und Logik

  Alt 1. Mai 2019, 09: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
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 05:43 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