Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Trennung von GUI und Logik, wie geht ihr vor? (https://www.delphipraxis.net/162373-trennung-von-gui-und-logik-wie-geht-ihr-vor.html)

Luckie 28. Nov 2017 20:31

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von jus (Beitrag 1387307)
Bei diesem einfachen Beispiel würde mich interessieren wie man sowas unter Delphi 2007 löst.

Mit einer Klasse (TRechner).

Chemiker 28. Nov 2017 21:55

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Hallo,

vielleicht hilft Dir das Video zu weiteren Erkenntnissen.

https://www.bing.com/videos/search?q...2F&FORM=VRDGAR

Bis bald Chemiker

haentschman 29. Nov 2017 08:09

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Moin...:P
Ein Minimalbeispiel entsprechend der Grafik...

VIEW:

Delphi-Quellcode:
unit View;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,

  Controller; // die View kennt eigentlich nur den Controller

type
  TfoView = class(TForm)
    edtNumber1: TEdit;
    edtNumber2: TEdit;
    btnAddition: TButton;
    edtResult: TEdit;
    procedure btnAdditionClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FController: TController;
    procedure DoCalculateResult(Sender: TObject; CalculateResult: Single);
  public

  end;

var
  foView: TfoView;

implementation

{$R *.dfm}

{ TfoView }

procedure TfoView.FormCreate(Sender: TObject);
begin
  FController := TController.Create;
  FController.OnCalculate := DoCalculateResult;
end;

procedure TfoView.FormDestroy(Sender: TObject);
begin
  FController.Free;
end;

procedure TfoView.btnAdditionClick(Sender: TObject); // Command
begin
  FController.Addition(StrToFloat(edtNumber1.Text),
                       StrToFloat(edtNumber2.Text));
end;

procedure TfoView.DoCalculateResult(Sender: TObject; CalculateResult: Single);
begin
  edtResult.Text := FloatToStr(CalculateResult);
end;

end.

CONTROLLER:

Delphi-Quellcode:
unit Controller;

interface

uses
  Model; // der Controller kennt eigentlich nur das Model

type
  TOnCalculate = procedure(Sender: TObject; CalculateResult: Single) of object;

  TController = class
  strict private
    FModel: TAddition; // oder die Klasse die alle Berechnungen implementiert (TCalculator)
    FOnCalculate: TOnCalculate;
    procedure DoCalculateResult(Sender: TObject; CalculateResult: Single);
  public
    constructor Create;
    destructor Destroy; override;
    property OnCalculate: TOnCalculate read FOnCalculate write FOnCalculate;
    procedure Addition(Number1, Number2: Single);
  end;

implementation

{ TController }


constructor TController.Create;
begin
  FModel := TAddition.Create;
  FModel.OnResult := DoCalculateResult; // Event einhängen
end;

destructor TController.Destroy;
begin
  FModel.Free;
  inherited;
end;

procedure TController.DoCalculateResult(Sender: TObject; CalculateResult: Single);
begin
  // dem Controller das Ergebnis mitteilen...wenn benötigt

  if Assigned(FOnCalculate) then // Refresh / Notify updates
  begin
    FOnCalculate(Self, CalculateResult);
  end;
end;

procedure TController.Addition(Number1, Number2: Single); // Command -> Use
begin
  // Prüfungen auf Gültigkeit nicht vergessen! :-)
  FModel.Calculate(Number1, Number2);
end;

end.
MODEL:
Delphi-Quellcode:
unit Model;

interface

type
  TOnResult = procedure(Sender: TObject; CalculateResult: Single) of object;

  TAddition = class
  strict private
    FOnResult: TOnResult;
    FCalculateResult: Single;
  public
    property OnResult: TOnResult read FOnResult write FOnResult;
    procedure Calculate(Number1, Number2: Single);
  end;

implementation

{ TAddition }

procedure TAddition.Calculate(Number1, Number2: Single); // Use
begin
  FCalculateResult := Number1 + Number2;
  if Assigned(FOnResult) then // Notify updates
  begin
    FOnResult(Self, FCalculateResult);
  end;
end;

end.

joachimd 29. Nov 2017 08:26

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Hallo haentschman,
ich würde hier aber der View den Controller und dem Controller das Model nicht fest verdrahten, sondern jeweils per Konstruktor als Interface mitgeben. Damit bleiben die Klassen voneinander unabhängig.

haentschman 29. Nov 2017 08:32

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Ich würde hier aber der View den Controller und dem Controller das Model nicht fest verdrahten
...viele Wege führen nach Rom. :P Mir ging es nur um das Prinzip entsprechend der kleinen Grafik...

freimatz 29. Nov 2017 08:42

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von Chemiker (Beitrag 1387433)
Hallo,
vielleicht hilft Dir das Video zu weiteren Erkenntnissen.
https://www.bing.com/videos/search?q...2F&FORM=VRDGAR
Bis bald Chemiker

Da geht es um MVVM und nicht um MVC (was ja nicht schlecht sein muss.)
Die Erklärung warum man so was macht ist sicher gut.
Allerdings ein Datenmodul als Basis zu nehmen halte ich für ... ... unschön

jus 29. Nov 2017 13:44

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von Chemiker (Beitrag 1387433)
Hallo,

vielleicht hilft Dir das Video zu weiteren Erkenntnissen.

https://www.bing.com/videos/search?q...2F&FORM=VRDGAR

Bis bald Chemiker

Vielen Dank! MVVM interessiert mich genauso. Das Video hat mir auch sehr geholfen.

Zitat:

Zitat von haentschman (Beitrag 1387443)
Moin...:P
Ein Minimalbeispiel entsprechend der Grafik...
...

Vielen Dank für das Beispiel, das werde ich mir heute am Abend genauer anschauen.

lg,
jus

Stevie 29. Nov 2017 14:01

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Bei 11:35 musst ich mir schon ein bisschen an den Kopf fassen - dass M-V-VM der gleichen Reihenfolge der Komponenten folgt wie sie auch M-V-C und M-V-P nutzen, darauf ist er nicht gekommen, oder? :wall:

Generell muss ich sagen, dass man das meiste Material zu MVVM aus der Delphiwelt in die Tonne kloppen kann, weil die meisten nicht verstehen, was der Kern von MVVM ist. Nur weil man UI von Businesslogik trennt macht man noch lange kein MVVM - in dieser Hinsicht ist das Video von Olaf schon eins der besten - dass ich seiner Implementierung und dem Argument, Delphi muss RAD sein, nicht ganz zustimme, steht auf einem anderen Blatt.

Ob man nun MVC, MVP, MVVM oder LMAA macht ist am Ende fast wurscht und hängt auch von den eigenen Bedürfnissen und Vorlieben ab. Ich bin inzwischen der Meinung, dass MVVM in Delphi mehr Schmerzen als Freude macht - zumindest solange bis man sich ein mehr oder minder mächtiges Framework gebaut hat (etwas, was ich mal gestartet aber aufgrund verschiedener Gründe abgebrochen habe).

Hier gibts einen kurzen aber guten Vergleich der gängisten Ansätze: https://stackoverflow.com/a/5124291/587106

freimatz 29. Nov 2017 16:14

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Wir verwenden schon seit Jahren MVVM mit einem selbstgebastelten FrameWork.
Ich stimme Stevie in fast allem zu. Fast - es macht auch mit FrameWork noch Schmerzen.

Rollo62 29. Nov 2017 17:24

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Setzt den jemand Daniel Teti's DMVC ein, was ist davon zu halten ?

Womöglich gibt es da auch Ansätze als View statt auf einem WebModul auf eine Form zu gehen ?
Ich habe da was von Messaging, etc. gesehen, was vielleicht auch ein gangbarer Weg wäre M V und C elegant zu entkoppeln und doch zu verbinden ...


Rollo

Stevie 29. Nov 2017 17:30

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von Rollo62 (Beitrag 1387528)
Setzt den jemand Daniel Teti's DMVC ein, was ist davon zu halten ?

Womöglich gibt es da auch Ansätze als View statt auf einem WebModul auf eine Form zu gehen ?
Ich habe da was von Messaging, etc. gesehen, was vielleicht auch ein gangbarer Weg wäre M V und C elegant zu entkoppeln und doch zu verbinden ...

AFAIK hat DMVC nix mit dem MVC im Sinne von UI-BL Trennung zu tun. Das ist ein pures REST Server Framework.
Ob du als Frontend ne Delphianwendung oder Angular Webseite hast, ist dem Ding egal.

Rollo62 29. Nov 2017 17:40

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Hallo Stevie,

Ok, dachte ich mir schon.
Hätte je sein können das er auch irgendwo ein Form-Frontend versteckt hätte.

Schade, könnte man sich aber vielleicht selber drumrumbauen, aber macht sowas Sinn ?
Ich persönlich finde den REST-Server Ansatz erstmal nicht verkehrt, weil es vielleicht
alle Möglichen View-Technologien (Delphi, JS, ...) offen hält.
Ist aber auch vielleicht mit Kanonen auf Spatzen wenn man den Server nicht braucht.

Rolf

mkinzler 29. Nov 2017 17:45

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Machbarkeitsstudie: https://bitbucket.org/sglienke/knockoff

Stevie 29. Nov 2017 18:01

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von mkinzler (Beitrag 1387531)

Ja, mehr aber auch nicht. ;)

Bei MVVM im Web (wie z.b. Knockout) gibt es einfach viel mehr Möglichkeiten, das einfach so schön in den HTML Code einzubetten und das Framework die ganze DOM Manipulation machen zu lassen. Und selbst mit WPF/XAML bekommst das besser hin als in Delphi. Da bleib ich lieber bei DB aware Controls und bau mein ViewModel/Controller/whatever als Memory- bzw Objekt- DataSet/DataModule. Da kann man dann mit den verschiedenen DataSet/Field states schon viel steuern, was die UI angeht (readonly, enabled, etc). Zumindest in der VCL. In FMX muss ich dann auch wieder aus Mangel an DB aware Komponenten mit den LiveBindings rumfummeln.

mkinzler 29. Nov 2017 18:05

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Für einfache Szenarien funktioniert es aber recht gut.

Rollo62 29. Nov 2017 18:35

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Ja, mehr aber auch nicht.
Leider :cry:

Zitat:

Da bleib ich lieber bei DB aware Controls und bau mein ViewModel/Controller/whatever ...
Vielleicht kommt ja bald mal Delphi + ExtJS ...

Rollo

mkinzler 29. Nov 2017 19:02

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Ja, aber nur für die Enterprise

freimatz 30. Nov 2017 09:00

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Was bitte ist ExtJS? Habe mal gegoogelt und nichts brauchbares rausgefunden. Will Sencha das nicht verkaufen? (Wer oder was Sencha auch immer ist)

Stevie 30. Nov 2017 09:02

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von freimatz (Beitrag 1387551)
Was bitte ist ExtJS?

Wenn du genau das in Google eingibst, sollte sich eine brauchbare Antwort in den ersten 3 Treffern finden lassen.

mkinzler 30. Nov 2017 09:06

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von freimatz (Beitrag 1387551)
Was bitte ist ExtJS? Habe mal gegoogelt und nichts brauchbares rausgefunden. Will Sencha das nicht verkaufen? (Wer oder was Sencha auch immer ist)

Ja und IDERA hat es gekauft.

p80286 30. Nov 2017 09:12

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Wenn ich die letzten Beiträge richtig verstanden habe, brauche ich ein Framework um Oberfläche und (Geschäfts-)Logik von einander zu trennen?

Gruß
k-H

mkinzler 30. Nov 2017 09:45

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Ein solches könnte dies erleichtern. Ohne muss man händisch viel glue code, welcher sehr ähnlich ist, immer wieder schreiben.

p80286 30. Nov 2017 09:57

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von mkinzler (Beitrag 1387562)
Ein solches könnte dies erleichtern. Ohne muss man händisch viel glue code, welcher sehr ähnlich ist, immer wieder schreiben.

danke für die prägnante Ausführung!

gruß
K-H

stahli 30. Nov 2017 10:13

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
@p80286

Kannst Du Deine Haltung mal etwas präzisieren?
So richtig ist mir nicht klar, worauf Du raus willst...


@all

Ich bevorzuge grundsätzlich Lösungen mit Databinding, die ohne Controller oder Presenter auskommen.
Dazu müssen Controls halt in der Lage sein, vorhandene Datenstrukturen zu erkennen und die GUI daraufhin anzupassen.
Eine ListBox wird also an die Autoliste des Fuhrparks gebunden und ein Edit an die Eigenschaft Lastname des Fahrer(objekt)s.
Ich möchte für die Verbindungen einfach keinen Code schreiben müssen.
Natürlich müssen dafür die Controls selbst wissen, wie sie mit der Datenschicht kommunizieren können.

p80286 30. Nov 2017 11:00

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
@Stahli
Ich hatte bisher den Eindruck, daß unbedingte Voraussetzung für die Trennung von Oberfläche und Logik ein Framework und die intime Kenntnis von MVC bzw. MVVM o. ä. ist. Wenn die "Denke" nicht vorhanden ist, helfen alle Hilfsmittel nicht weiter. Man muß also zuerst die Notwendigkeit einsehen und Verstehen, und dann kann man sich an irgendwelchen Thesen orientieren.

Und Markus kann nun mal unerreicht prägnant formulieren.

Gruß
K-H

stahli 30. Nov 2017 11:12

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Ah, ok, ich hatte da etwas Sarkasmus aus Deinen Beiträgen heraus gelesen.
Aber ich nehme gleich meine Tropfen ein, dann wird das schon wieder! :stupid:

Mavarik 30. Nov 2017 11:41

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Hallo Zusammen...

Schade das es von den Forentage keine Videos gibt...

In mein MVVM-Lite Vortrag habe ich genau gezeigt, wie einfach man MVVM (oder was ich dafür halte) ohne Framework mit wenigen Handgriffen machen kann.

Abgesehen davon : je weniger ich im OI klicken muss, umso schneller bin ich...
Wenn man dann noch die ein oder andere Factory hat geht MVVM kaum langsamer zu programmieren als IDE Klick on Button and go...
Ein bisschen mehr aufwand um zwischen den einzelnen Schichten hin und her zu wechseln...

Nix gegen Olaf's Video, Theorie ok, aber die Umsetzung würde ich so Hardcoded NIE machen. Lieber ein Interface erzeugen, dass Übergeben, am besten aus einer Factory. Außerdem verfolge ich gerne den CRUD Ansatz als Basis zu nehmen, dass erleichtert immer eine Umsetzung für eine App wo die Daten auf einem REST-Server liegen usw.

Mavarik

stahli 30. Nov 2017 11:52

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
... wolltest Du dazu nicht mal ein kleines Video machen?

Mavarik 30. Nov 2017 11:58

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von stahli (Beitrag 1387579)
... wolltest Du dazu nicht mal ein kleines Video machen?


ja, will ich immer noch.
[OT]
Ich schiebe leider noch einen Berg von Aufgaben vor mehr her, bis dafür Zeit ist...
[/OT]

freimatz 30. Nov 2017 12:13

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von Mavarik (Beitrag 1387578)
Nix gegen Olaf's Video, Theorie ok, aber die Umsetzung würde ich so Hardcoded NIE machen. Lieber ein Interface erzeugen, dass Übergeben, am besten aus einer Factory. Außerdem verfolge ich gerne den CRUD Ansatz als Basis zu nehmen, dass erleichtert immer eine Umsetzung für eine App wo die Daten auf einem REST-Server liegen usw.

Du redest schon von MVVM? Wir machen seit vielen Jahren MVVM (nennen es zumindest so). Interfaces sind da auch dabei. Aber ich habe keinen Schimmer was das mit CRUD zu tun hat. Wie geht das Binding bei dir? Also wie kommen z.B. Double Werte vom viewmodel an eine TEdit-Control? Und wie bekommt das viewmodel Bescheid wann sich was geändert hat?
Bei uns macht man in der UI z.B.:
BindingManager.NewBinding(viewmodel.TED1, edTED1, BindingModeET.Bidirectional);
Da ist TED1 ein view item im viewmodel und edTED1 ein Edit-Control.

Mavarik 30. Nov 2017 13:16

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von freimatz (Beitrag 1387583)
Du redest schon von MVVM? Wir machen seit vielen Jahren MVVM (nennen es zumindest so). Interfaces sind da auch dabei. Aber ich habe keinen Schimmer was das mit CRUD zu tun hat. Wie geht das Binding bei dir? Also wie kommen z.B. Double Werte vom viewmodel an eine TEdit-Control? Und wie bekommt das viewmodel Bescheid wann sich was geändert hat?
Bei uns macht man in der UI z.B.:
BindingManager.NewBinding(viewmodel.TED1, edTED1, BindingModeET.Bidirectional);
Da ist TED1 ein view item im viewmodel und edTED1 ein Edit-Control.

Also: Ich habe nie statische Datenbankverbindungen, nie ein Datenmodul, nie eine Datenbankkomponente irgendwo hin geklickt. Kein DataSource kein NIX.

Ich erzeuge alles dynamisch und behandle alles als währe es ein REST Request zu einem Server. Mein Model hat jeweils eine Memory Repräsentation eines Datensatzes oder einer Liste von Datensätzen. i.d.R. nicht mehr als doppelte der StringGridInViewRowCount.

Für die Bindung von View->ViewModel habe ich eine eigene Verbindungsklasse geschrieben für die andere Richtung erzeuge ich einen PropertyChange Multicast-Event.

Mein Model kann i.d.R. auch immer ein Autosync (für Apps) lokale SQLite <-> REST Server. Beim schreiben, wird immer erst in die lokale SQLite geschrieben und dann im Thread per REST zum Server beim Lesen wird - falls eine Internetverbindung besteht erst ein TimeStamp-Vergleich ausgeführt und falls der Server nicht neuere Daten hat aus der lokalen SQLite gelesen...

Da ich immer - bei jeder Software - diesen Ansatz verfolge, brauche ich bei einer Software mit einem ständigen Datenbankzugang, nur das localSync Interface weglassen und alles läuft ohne den Zwischenschritt...

Ich hoffe das beantwortet Deine Frage und war nicht zu offtopic... :stupid:

Mavarik

freimatz 30. Nov 2017 15:16

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Es geht doch immer noch um "Trennung von GUI und Logik" ;-)

DAs was MVVM betrifft sehe ich in deinem Satz: "Für die Bindung von View->ViewModel habe ich eine eigene Verbindungsklasse geschrieben für die andere Richtung erzeuge ich einen PropertyChange Multicast-Event."
Der Rest ist doch alles ViewModel<->Model - oder?
Und das tritt doch auch unr zu wenn man eine DB hat. Bei uns hat das UI, das Viewmodel und das Model erst mal nichts mit DB zu tun.

Die oben geschriebene Verbindungsklasse - gibts die dann für jede View seperat implementiert?

mkinzler 30. Nov 2017 15:40

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Und das tritt doch auch unr zu wenn man eine DB hat.
Ein Model hat man auch ohne Datenbank.

freimatz 30. Nov 2017 15:52

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Ja eben. Mich irriitert dass er so viel schreibt, was ich eher in Richtung DB sehe wie REST, Server, Datensatz, Datensätze, Grid, SQLite und Datenbankzugang.
Aber egal, mir gings um MVVM und da eher um UI<->Viewmodel

Mavarik 30. Nov 2017 16:10

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von freimatz (Beitrag 1387622)
Ja eben. Mich irriitert dass er so viel schreibt, was ich eher in Richtung DB sehe wie REST, Server, Datensatz, Datensätze, Grid, SQLite und Datenbankzugang.
Aber egal, mir gings um MVVM und da eher um UI<->Viewmodel

Es kommt ein bisschen darauf an, ob die Datenhaltung im ViewModel oder im Model ist.

Hier findet man oft sehr unterschiedliche Ansätze..

Nach dem Motto : Das ViewModel hat nur die Status- und Steuerungslogik die Daten liegen immer im Model...

oder

Das Viewmodel hält zusätzlich die Daten der View und das Model ist nur für eine Datenbank-Schicht da.

Ich habe bereits beide Ansätze versucht und verwende es so wie es optimal für die Aufgabe ist.

Ob man den "Aufwand" triebt für ein Fenster, dass keine "Daten" benötigt ist die andere Frage...

Stevie 30. Nov 2017 16:11

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von stahli (Beitrag 1387569)
Ich bevorzuge grundsätzlich Lösungen mit Databinding, die ohne Controller oder Presenter auskommen.
Dazu müssen Controls halt in der Lage sein, vorhandene Datenstrukturen zu erkennen und die GUI daraufhin anzupassen.
Eine ListBox wird also an die Autoliste des Fuhrparks gebunden und ein Edit an die Eigenschaft Lastname des Fahrer(objekt)s.
Ich möchte für die Verbindungen einfach keinen Code schreiben müssen.
Natürlich müssen dafür die Controls selbst wissen, wie sie mit der Datenschicht kommunizieren können.

Und wo implementierst du, dass man einen Fahrer mit nur Führerschein Klasse B nicht in den 12-Tonner setzen kann?

Zitat:

Zitat von Mavarik (Beitrag 1387624)
Es kommt ein bisschen darauf an, ob die Datenhaltung im ViewModel oder im Model ist.

Hier findet man oft sehr unterschiedliche Ansätze..

Nach dem Motto : Das ViewModel hat nur die Status- und Steuerungslogik die Daten liegen immer im Model...

oder

Das Viewmodel hält zusätzlich die Daten der View und das Model ist nur für eine Datenbank-Schicht da.

Ich habe bereits beide Ansätze versucht und verwende es so wie es optimal für die Aufgabe ist.

Ob man den "Aufwand" triebt für ein Fenster, dass keine "Daten" benötigt ist die andere Frage...

Eigentlich ist es recht unmissverständlich definiert - siehe https://msdn.microsoft.com/en-us/lib...8246.aspx#sec7

Die Frage ist eher, wie sehr man die Daten kapselt. Wenn jemand sagt, meine Daten sind in Form eines Datasets, dann kann man das natürlich argumentieren, dass das VM die einfach durchreicht.
Ob man damit allerdings eine gute Testbarkeit und Kapselung erreicht, stell ich mal in Frage.

Auch bestimmte Anforderungen beeinflussen, wie sehr das VM das M duplizieren muss. Es gibt zum Beispiel VM Basisimplementierungen, die das Edit/Save/Cancel implementieren und dann an das View bloß eine Kopie der Modelldaten binden und beim Save bzw Cancel die Änderungen zurück kopieren oder verwerfen.

Fritzew 30. Nov 2017 16:47

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Auch bestimmte Anforderungen beeinflussen, wie sehr das VM das M duplizieren muss. Es gibt zum Beispiel VM Basisimplementierungen, die das Edit/Save/Cancel implementieren und dann an das View bloß eine Kopie der Modelldaten binden und beim Save bzw Cancel die Änderungen zurück kopieren oder verwerfen
Wir benutzen diesen Ansatz eigentlich immer. CAD Bereich. Der Anwender ändert etwas in einem Fenster und bekommt das direkt visualisiert. Da kann er dann "rumspielen" und bei Ok bleibt die letzte Änderung erhalten und wird committed. Ansonsten geht es zurück auf den Original Stand. Hat den Vorteil dass der Undo Buffer erst bei OK belegt wird.

Mavarik 30. Nov 2017 17:03

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von Stevie (Beitrag 1387626)
Eigentlich ist es recht unmissverständlich definiert - siehe https://msdn.microsoft.com/en-us/lib...8246.aspx#sec7

Die Frage ist eher, wie sehr man die Daten kapselt.

Ja "unmissverständlich" wird gesagt, dass das VM die Daten aus dem Model auch ggf. Interpretiert und ggf. anders an die View weiter gibt.

Also hat das VM ggf. auch intern eine eigenen Datenbestand für die View...

Stevie 30. Nov 2017 17:52

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Zitat:

Zitat von Mavarik (Beitrag 1387635)
Zitat:

Zitat von Stevie (Beitrag 1387626)
Eigentlich ist es recht unmissverständlich definiert - siehe https://msdn.microsoft.com/en-us/lib...8246.aspx#sec7

Die Frage ist eher, wie sehr man die Daten kapselt.

Ja "unmissverständlich" wird gesagt, dass das VM die Daten aus dem Model auch ggf. Interpretiert und ggf. anders an die View weiter gibt.

Also hat das VM ggf. auch intern eine eigenen Datenbestand für die View...

Der Kernpunkt ist, dass das VM die Kontrolle darüber hat, was in beide Richtungen fließt.

Lass uns nochmal kurz definieren, was bei MVVM Model und ViewModel sind.

Bei dem Model kann es sich um eine simple TCustomer Klasse mit 5 string Eigenschaften und sonst nix handeln oder um eine TSpeicherDruckUndSchickEmailsKlump Klasse mit siebenundöffzig Methoden.

Das ViewModel abstrahiert die Funktionialität des Models, die in der View benutzt wird und bereitet sie entsprechend auf. Wenn ich von den 5 Eigenschaften nur 3 Anzeige, dann gibt es möglicherweise nur genau diese 3 Eigenschaften im ViewModel (caching, edit, save, cancel etc mal außen vor gelassen). Wenn es nun so sein soll, dass ich die 3. Eigenschaft nur befüllen kann, wenn die 2 anderen Eigenschaften bestimmte Werte haben, dann gibt es eine "Eigenschaft3Enabled" Eigenschaft im ViewModel, welche an das entsprechende UI Control für diese Eigenschaft gebunden wird und durch Änderungen der anderen beiden Eigenschaften im ViewModel beeinflusst wird. Hierbei sorgen die Bindings und ein entsprechende Benachrichtigungssystem für das Updaten in beide Richtungen:

In der UI in den Controls für Eigenschaft 1 oder 2 was geändert -> binding aktualisiert das VM -> "Eigenschaft3Enabled" wird ggf verändert -> "Eigenschaft3Enabled hat sich geändert" Notification triggert -> binding bekommt das mit -> UI Control für Eigenschaft 3 wird entsprechend an oder ausgeschaltet

D.h. irgendwelche Businesslogik wird in den meisten Fällen nichtmal im ViewModel gehandhabt sondern im Model. Das ViewModel ist quasi nur die Abstraktion der UI. Dort steht drin, dass bei der Konstellation XY die CheckBox Z angezeigt wird oder nicht.

Und genau jetzt ergibt sich oft die Tücke, dass gewisse Dinge dann doch irgendwie Businesslogik sind und Teil des Models sind (komplexe Regel validierung, etc), aber doch bitte in der UI reflektiert werden soll. Das muss dann immer komplett durch das ViewModel hin und zurück fließen - guckstu https://stackoverflow.com/questions/...or-a-viewmodel

Das heißt also, dass hier das VM schon mehr Teil der UI als der Businesslogik ist - schaust du hier: https://stackoverflow.com/questions/...ttern-and-mvvm
Wenn du dir den 2. Grund anschaust, warum MVVM so toll ist/sein soll, dann wird klar, warum das in Delphi in dieser Form so schnell zusammen fällt, da gibs kein Blend. Rapid Prototyping funktioniert bei uns ein bisschen anders (TPrototypeBindSource, TClientDataSet etc).

stahli 30. Nov 2017 21:30

AW: Trennung von GUI und Logik, wie geht ihr vor?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Stevie (Beitrag 1387626)
Und wo implementierst du, dass man einen Fahrer mit nur Führerschein Klasse B nicht in den 12-Tonner setzen kann?

Mit Validierungsregeln an Klassen und an Properties.
Die GUI weiß, dass es Validierungsregeln geben kann und wird diese Informationen entsprechend automatisch benutzen.
Im Bild (Machbarkeitstest) ist schon mal eine Regel hinterlegt (das können Attribute wie NotEmpty oder ganze Funktionen sein) und die GUI zeigt den Regelverstoß an.
Außerdem zeigt sie gleich noch automatisch an, wenn in einem anderen Client gerade die selbe Eigenschaft geändert wird.
Man braucht also nur die Regeln definieren und das Framework macht den Rest.

Übrigens kann man dann auch einfach z.B. einen OkButton.Valid an MyPerson.Valid binden. Der wird dann Enabled, wenn das Objekt valide ist und sonst listet er die Probleme auf.
Oder man bindet OkButton.Enabled an MyPerson.IsValid, so dass er nur enabled/disabled wird und zeigt die Validierungsprobleme an den anderen Controls an.

Das Projekt ist allerdings noch in Arbeit aber dort will ich hin und teilweise funktioniert das auch schon super.


Bezüglich Deines Beispiels "nicht in den 12-Tonner setzen kann" müsste man klären, was das genau heißt und wo das Problem auftreten kann.
Auf jeden Fall müsste eine Eigenschaft oder eine Klasse die Validität/Akzeptanz prüfen.
Wenn das hinein setzen z.B. über Drag&Drop erfolgt, müsste der LKW prüfen, ob der Fahrer den LKW fahren darf und ggf. DropAccept verweigern.
Der Fahrer selbst ist ja nicht invalide, aber beim Starten des LKW müsste ggf. ein Fehler ausgegeben werden.
Genau kann ich das jetzt so auch nicht sagen. Jedenfalls müssen die Klassen und Properties Validierungen oder einfache Checks/Funktionen ausführen, die die GUI abfragen kann.
An der Stelle, wo ich jetzt etwas schwimme, müsste man bei Einsatz eines Controllers sicher auch gut überlegen, wie man das 12-Tonner-Problem genau umsetzt und in der GUI darstellt.



Zitat:

Zitat von Stevie (Beitrag 1387642)
Das ViewModel abstrahiert die Funktionialität des Models, die in der View benutzt wird und bereitet sie entsprechend auf. Wenn ich von den 5 Eigenschaften nur 3 Anzeige, dann gibt es möglicherweise nur genau diese 3 Eigenschaften im ViewModel (caching, edit, save, cancel etc mal außen vor gelassen).

Eben diese Doppelung will ich mir ersparen und binde einfach nur drei Controls an 3 von 5 Eigenschaften.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:16 Uhr.
Seite 4 von 5   « Erste     234 5      

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