Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Funktion und Darstellung trennen (https://www.delphipraxis.net/126091-funktion-und-darstellung-trennen.html)

scrat1979 17. Dez 2008 21:09


Funktion und Darstellung trennen
 
Hallo zusammen!

Ich bin gerade dabei, meinen Programmierstil etwas zu verbessern. Hier im Forum stößt man öfters auf Aussagen wie "Du mußt Funktion und Darstellung eines Programmes klar trennen". Was genau ist denn damit gemeint? Gibt es hierzu evtl. ein Beispiel oder sogar ein Programm mit Source, um dies nachvollziehen zu können?? Über die SuFu oder unter Google habe ich leider nichts gefunden :-(

Danke im Voraus,
SCRaT

Noedel 17. Dez 2008 21:25

Re: Funktion und Darstellung trennen
 
Damit ist nur gemeint, dass du die Sachen wie Rechnungen allgemein solche Prozesse von den anderen wie Ausgabe, Gestaltung
trennen sollst. (bzw. kannst, weil es einfach "nur" schöner ist)

taaktaak 17. Dez 2008 21:29

Re: Funktion und Darstellung trennen
 
Hmmmm.... "einfach nur schöner"? Nee, also das kann nicht ernst gemeint sein! Wenn die Programme umfangreicher werden, ist es so ziemlich der einzige Weg sich noch im Source zurecht zu finden. Aber, zumindest mir geht es so, es ist oft nicht gerade einfach dieses Prinzip konsequent anzuwenden.

scrat1979 17. Dez 2008 21:32

Re: Funktion und Darstellung trennen
 
Also ist damit gemeint, z.B. umfangreiche Berechungen, Speicherungen in Datei etc. in eigene Proceduren zu packen und diese dann aufzurufen??

Noedel 17. Dez 2008 21:34

Re: Funktion und Darstellung trennen
 
genau so in der Art.
So sollst du zb nicht rechnung, Ausgabe und vllt noch was Visualisiertes in eine Procedure oder gar auf einen Button legen sondern für jeden "Schritt" (Vllt sagt dir EVA was) ne neue Procedure anlegen ;)

Apollonius 17. Dez 2008 21:36

Re: Funktion und Darstellung trennen
 
Hauptsächlich geht es meiner Meinung nach primär darum, dass man seine Daten nicht in Labels oder Listboxen speichert, sondern sie in Variablen vorhält. Der Programmablauf sollte also nicht gestört werden, selbst wenn extern irgendwelche Control-Eigenschaften verändert werden. Man bekommt sonst auch enorme Schwierigkeiten, wenn man später mal die GUI verändern will und nun ziemlich viel umschreiben muss, weil sich die Datenspeicherung verändert hat.

sx2008 18. Dez 2008 05:52

Re: Funktion und Darstellung trennen
 
Hier mal ein Beispiel, das gleich zwei Fehler enthält:
Delphi-Quellcode:
function BerechneZinsesZins:double;
var
  kapital, zins : double;
  jahre, i : integer;
begin
  kapital := StrToFloat(Form1.EditKapital);
  zins   := StrToFloat(Form1.EditZins) / 100.0;
  jahre  := IntToStr(Form1.EditJahre);
  if jahre <= 0 then
  begin
    ShowMessage('Die Anzahl der Jahre muss grösser 0 sein!');
    result := 0;
    exit;
  end;
  Result := kapital;
  for i := 1 to jahre do
    Result := Result * (1.0 + zins);
end;
1. Fehler
Die Bussinesslogik ist untrennbar mit der Benutzeroberfläche verkoppelt.
Richtig wäre es, die Werte kapital, Zins und jahre als Parameter zu übergeben
2. Fehler
Es wird ShowMessage verwendet, um einen Fehler anzuzeigen.
Dies wird immer wieder falsch gemacht, denn ShowMessage verhindert,
dass man Programmcode in einem anderen Kontext benützen kann.
Man möchte die Funktion vielleicht in einer Schleife aufrufen oder in einem Webservice anwenden.
Richtig kann nur sein eine Exception zu "raisen".

guidok 18. Dez 2008 06:07

Re: Funktion und Darstellung trennen
 
Zitat:

Also ist damit gemeint, z.B. umfangreiche Berechungen, Speicherungen in Datei etc. in eigene Proceduren zu packen und diese dann aufzurufen??
Das ist nicht unbedingt damit gemeint (das ist eher prozedurale Programmierung).


Die Daten und deren Verarbeitung sollten in einer von der GUI getrennten Stuktur abgelegt sein.

Beispielsweise ein StringGrid (GUI), welches die Daten aus einer Tabelle (Datentabelle, z.B. eine Collection) nur darstellt. Änderungen werden nur an der Tabelle durchgeführt und anschließend wird das Grid neu angezeigt.

Nicht, weil es einfach "nur" schöner ist, sondern um einerseits bei Änderungen an der GUI an der Datenlogik nichts verändern zu müssen und andererseits auch, um bei Änderungen an der Datenlogik an der GUI nichts verändern zu müssen.

Die praktische Umsetzung ist häufig leider nicht ganz einfach, ich würde die Daten in ein Objekt verpacken und die entsprechenden Methoden für den Zugriff bereit stellen.

Ich versuche mal ein Beispiel:

Hier wird bei ButtonClick ein EditDialog ausgeführt, dem ein neuer Datensatz übergeben wird, der in diesem Fall NEU (Add) hinzugefügt wurde. Das Datenobjekt "Users" stellt dazu die Methode "Add" bereit und diese liefert einen leeren Datensatz vom Typ TUser zurück (hier verkürzt gezeigt).

Bei Doppeklick auf die Listbox, wird ebenfalls der EditDialog geöffnet, diesmal mit den Daten eines bestehenden Users, der über den Index (der Index der Liste entspricht dabei dem Index der Kollektion, das ist wichtig!) aus der Kollektion geholt wird.

Die Prozedur "UpdateList" hat nichts weiter zu tun, als die Listenanzeige neu anzuzeigen.

Delphi-Quellcode:
  //Einzelnes User-Objekt
  TUser = class(TCollectionItem)
    ...
    public
      property Name: String read...
      property Passwort: String read...
    end;

  //Users Kollektion, hier steckt das "Add"
  TUsers = class(TCollection)
    ...
  public
    //Add ist eine Funktion mit einem Rückgabewert vom Typ TUser
    function Add: TUser;
  end;

  //Hier wird ein neuer User eingefügt und seine Daten bearbeitet
procedure TBenutzerverwaltung.btNeuClick(Sender: TObject);
begin
  //Neuen Eintrag anlegen
  fEditDialog.Edit(Users.Add);
  UpdateList;
end;

procedure TfBenutzerverwaltung.ListBox1DblClick(Sender: TObject);
begin
  //Eintrag bearbeiten
  fEditDialog.Edit(Users[Listbox1.ItemIndex]);
  UpdateList;
end;

procedure TBenutzerverwaltung.UpdateList;
var i: Integer;
begin
  Listbox1.Clear;
  if Users.Count > 0 then begin
    for i := 0 to Users.Count - 1 do begin
      Listbox1.Items.Add(Users[i].Name);
    end;
  end;
end;
Alle Klarheiten beseitigt?


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:59 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