Delphi-PRAXiS
Seite 2 von 7     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   MVVM in der Realität (https://www.delphipraxis.net/176478-mvvm-der-realitaet.html)

Union 10. Sep 2013 14:04

AW: MVVM in der Realität
 
Zitat:

Zitat von stahli (Beitrag 1227830)
Der Unterschied zu meinem Framework ist, dass bei mir beide Schichten (BL&Daten sowie GUI) völlig getrennt erzeugt werden und existieren und das Framework lediglich die GUI-Controls an bestimmte Daten (Objekteigenschaften) bindet.

Wo ist denn da der Unterschied? Du hast:
  1. GUI (View)
  2. Framework (Viewmodel)
  3. Daten & BL (Model)

stahli 10. Sep 2013 14:14

AW: MVVM in der Realität
 
Ich habe nicht nachvollziehen können, wann welcher Teil erzeugt, initialisiert und aufgerufen wird.
Das gesamte Handling hat sich mir nicht erschlossen. Entsprechend konnte ich es nicht als einfach und erstrebenswert einordnen.

Ich will es ja nicht schlecht reden. Es war nur MEIN BISHERIGER Eindruck von der Sache. Bin halt etwas einfach gestrickt. ;-)

stahli 10. Sep 2013 15:56

AW: MVVM in der Realität
 
Gleich nochmal von mir (aber kein push):

Wie wäre es mit einer kleinen Aufgabestellung (z.B. Eltern und Kinder verwalten oder so), die mit verschiedenen Ansätzen per Videodokumentation vorgestellt werden?

Man könnte sich auf eine kleine Aufgabe einigen.
Wer teilnehmen will kann dann die Aufgabe mit seiner bevorzugten Arbeitsumgebung von Null an erstellen und dies mit Screenrecorder dokumentieren.

Ich wäre RIESIG GESPANNT auf die Ergebnisse und würde mich mit meinem ssFramework beteiligen.


Mein Projektvorschlag:
- Elternpaare registrieren (Vorname, Nachname, Alter, Geschlecht)
- Kinder zuordnen (ebenfalls Vorname, Nachname, Alter, Geschlecht)
- Daten speichern und laden
- Formularbreite und -höhe ändern über SpinBoxen und Formularcaption über Edit (wegen Demonstration des DataBinding)

stahli 12. Sep 2013 12:36

AW: MVVM in der Realität
 
War das wieder eine Schnapsidee von mir?
Ich denke mir, man könnte so einen Überblick über die attraktivsten Arbeitsansätze finden...

Union 12. Sep 2013 14:17

AW: MVVM in der Realität
 
Scheint ja wohl daran zu liegen dass es noch keiner so wirklich nutzt.

stahli 12. Sep 2013 14:46

AW: MVVM in der Realität
 
Ich weiß immer nicht, ob ich der Zeit um einige Jahre voraus bin oder hinterher hinke oder örtlich vielleicht doch woanders hin gehöre... :wink:

Es gibt ja immer wieder schlaue Hinweise, wie man (vielleicht auch ohne Delphi) Projekte am einfachsten, übersichtlichsten, schönsten und stabilsten aufbaut. Die Bemerkungen sind für mich aber zu abstrakt.

Ich würde mir alle entsprechenden Demovideos begeistert reinziehen.
Wenn man (vielleicht in einem eigenen Thread) eine kleine Aufgabe abstimmt würde ich mit meinem Framework auch gern den Anfang machen... (unter MVVM fällt das allerdings m.E. nicht wirklich - aber es unterstützt gut bei der Projektentwicklung)

Union 12. Sep 2013 15:23

AW: MVVM in der Realität
 
Also ich habe einen Lösungsansatz, den ich in Ausschnitten beschreibe.

Die View ist ein normales TForm. Beim Erzeugen wird das Binding erstellt.
Delphi-Quellcode:
constructor TfrmMain.Create(AOwner: TComponent);
begin
  ViewModel := TViewModelKunde.create;
  inherited;

  // Binding einzeln erzeugen
  FBindingList   := TBindingList.Create;
  FNameBindObject := TEditBinding.Create;
  FNameBindObject.Control := edtNameTest;
  FNameBindObject.ControlProp := 'Text';
  FNameBindObject.BindObject := ViewModel.Kunde;
  FNameBindObject.BindProp := 'Name';
  // Und hinzufügen
  FBindingList.Add(FNameBindObject);
  // Oder direkt
  FBindingList.Add(TEditBinding.Create(edtKdNrTest, ViewModel.Kunde, 'Text', 'Kdnr'));
  // Hier wird alles initialisiert
  FBindingList.Load;
end;
Im Viewmodel wird dann die UI-Relevante Logik implementiert, z.b. ob gespeichert werden darf.
unit Viewmodel.Kunde;

Delphi-Quellcode:
interface

uses Model.Kunde;

type
  TViewModelKunde = class
  strict private
    FKunde: TKunde;
    procedure SetKunde(const Value: TKunde);
    function GetCanSave: boolean;
  published
    constructor create;
    property Kunde : TKunde read FKunde write SetKunde;
    procedure Save;
    property CanSave : boolean read GetCanSave;
  end;

// Kann aus dem View heraus benutzt werden um festzustellen ob z.B. Speicherung zulässig
function TViewModelKunde.GetCanSave: boolean;
begin
  result := FKunde.IsValid;
end;
Und das Model stellet eben die Daten dar, in diesem Fall ganz schlicht.
Delphi-Quellcode:
unit Model.Kunde;

interface
uses
  System.Classes;

type
  MaxLen = class(TCustomAttribute)
  private
    FMaxLen : integer;
  public
    constructor Create(const ALength : integer); overload;
    // Per Konvention muss die Attribut-Property immer "Value" heißen
    property Value : integer read FMaxLen;
  end;

  TKunde = class
  strict private
    FName: string;
    FKdNr: integer;
    FStrasse: string;
    procedure SetKdNr(const Value: integer);
    procedure SetName(const Value: string);
    procedure SetStrasse(const Value: string);
    function GetIsValid: boolean;
  public
    property KdNr : integer read FKdNr write SetKdNr;
    [MaxLen(20)]
    property Name : string read FName write SetName;
    property Strasse : string read FStrasse write SetStrasse;
    property IsValid : boolean read GetIsValid;
  end;

implementation

{ TKunde }

function TKunde.GetIsValid: boolean;
begin
  result := (FKdNr > 0) and
            (FName <> '') and
            (FStrasse <> '');
end;

procedure TKunde.SetKdNr(const Value: integer);
begin
  FKdNr := Value;
end;

procedure TKunde.SetName(const Value: string);
begin
  FName := Value;
end;

procedure TKunde.SetStrasse(const Value: string);
begin
  FStrasse := Value;
end;

{ MaxLen }

constructor MaxLen.Create(const ALength: integer);
begin
  FMaxLen := ALength;
end;
Das ganze wird verbunden durch das Binding. Wenn ein Binding erzeugt wird mit z.b.
Delphi-Quellcode:
TEditBinding.Create(edtKdNrTest, ViewModel.Kunde, 'Text', 'Kdnr')
TEditBinding.Load
wird eigentlich nur folgendes festgelegt:

1. edtKdnrTest.Text entspricht ViewModel.Kunde.Kdnr
2. Evtl. im Model angelegte Attribute werden ausgelesen und in die UI eingetragen (Hier MaxLen)
3. Der OnExit Event wird durch einen eigenen Event überschrieben, der Original-Event wird intern gemerkt

Immer wenn jetzt der OnExit des Edit aufgerufen wird, wird zunächst der Inhalt an das Model übertragen und dann ein evtl. vorher vorhandener Original-Event aufgerufen.
Delphi-Quellcode:
procedure TCustomBinding.DoNotify(Sender: TObject);
begin
  Save;
  if Assigned(FOldNotify) then
    FOldNotify(Sender);
end;

procedure TCustomBinding.Save;
var
  AValue : Variant;
begin
  AValue := GetPropValue(FControl, FControlProp);
  SetPropValue(FBindObject, FBindProp, AValue);
end;

Patito 12. Sep 2013 16:30

AW: MVVM in der Realität
 
Zitat:

Zitat von Union (Beitrag 1228161)
Scheint ja wohl daran zu liegen dass es noch keiner so wirklich nutzt.

Für mich ist MVVM eher etwas, das für kleine Projekte zu komplex ist, und für komplexe Projekte zu klein.
Als ich mein GUI-Framework geschrieben habe, habe ich zuerst mit Bindings experimentiert, bin dann aber
recht schnell Richtung MVP/MVC gegangen.

MVVM neigt einfach dazu das ViewModel komplett zu overengineeren. Mit MVP mit einem richtigen Controller statt
starrer Bindings ist man einfach flexibler.

Meine Praxiserfahrung: Eine Controller Klasse ist deutlich flexibler als ein Haufen starrer Bindings.
(z.B. kennt der Controller den View und kann nach einer Eingabe den Focus einfach auf ein passendes Feld setzen
- wenn man das über das ViewModel lösen muss, muss man sich erst mal Gedanken über Focus-Status Properties machen)

Wenn man es unbedingt braucht, kann man sich in den Controller dann immer noch ein paar starrere Bindings einbauen
(ich glaube Joanna Carter hat das damals "Interactor" genannt).

Union 12. Sep 2013 17:13

AW: MVVM in der Realität
 
Zitat:

Zitat von Patito (Beitrag 1228192)
Zitat:

Zitat von Union (Beitrag 1228161)
Scheint ja wohl daran zu liegen dass es noch keiner so wirklich nutzt.

Meine Praxiserfahrung: Eine Controller Klasse ist deutlich flexibler als ein Haufen starrer Bindings.
(z.B. kennt der Controller den View und kann nach einer Eingabe den Focus einfach auf ein passendes Feld setzen

Eben das sollte IMHO nicht direkt passieren. Ich würde da Passive View präferieren. Herangehensweise war ja auch die Austauschbarkeit des Views. Ich will doch im Presenter so was eben nicht haben:

Delphi-Quellcode:
FView.KundenEdit.SetFocus;


Oder habe ich Dich falsch verstanden?

mquadrat 13. Sep 2013 11:37

AW: MVVM in der Realität
 
Das was ich aktuell in der Mache habe, entspricht so ziemlich dem, was Union geschrieben hat. Wobei ich immer noch am Zweifeln bin, ob es nicht doch irgendwie machbar wäre unsere Legacy-Anwendungen mit DSharp zusammen zu bringen. Man braucht das Rad ja nicht krampfhaft neu zu erfinden.

@Patito
Der Vorteil von ViewModels ist vor allem die Tatsache, dass man die GUI weitgehend Unit-testen kann. Der Austausch der Views wird IMHO erst interessant, wenn man X-Plattform entwickelt. Bei allem was stärkeren Wert auf das Design legt als 0815-Delphi hat man noch den Vorteil, dass das ViewModel eine verlässliche Schnittstelle zwischen Frontend-Designer und Backend-Entwickler darstellt.
Aber MVP geht sicher auch. Das war ja auch das Pattern, dass Microsoft anfangs für .NET empfohlen hat. MVVM kam da ja auch erst später auf.

@stahli
Das kann man sicher mal machen, auch wenn ich nicht glaube, dass die Lösungen da sooo unterschiedlich ausfallen werden. Delphi-Entwickler sind nun mal eben eher traditionell. Dazu kommt, dass Emba MVVM nicht wirklich promotet. Ich wäre schon froh, wenn man beim uses .* nutzen könnte (oder hab ich das Feature etwa übersehen?)


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:48 Uhr.
Seite 2 von 7     12 34     Letzte »    

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