![]() |
AW: MVVM in der Realität
Zitat:
|
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. ;-) |
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) |
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... |
AW: MVVM in der Realität
Scheint ja wohl daran zu liegen dass es noch keiner so wirklich nutzt.
|
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) |
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:
Im Viewmodel wird dann die UI-Relevante Logik implementiert, z.b. ob gespeichert werden darf.
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; unit Viewmodel.Kunde;
Delphi-Quellcode:
Und das Model stellet eben die Daten dar, in diesem Fall ganz schlicht.
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;
Delphi-Quellcode:
Das ganze wird verbunden durch das Binding. Wenn ein Binding erzeugt wird mit z.b.
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;
Delphi-Quellcode:
wird eigentlich nur folgendes festgelegt:
TEditBinding.Create(edtKdNrTest, ViewModel.Kunde, 'Text', 'Kdnr')
TEditBinding.Load 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; |
AW: MVVM in der Realität
Zitat:
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). |
AW: MVVM in der Realität
Zitat:
Delphi-Quellcode:
FView.KundenEdit.SetFocus;
Oder habe ich Dich falsch verstanden? |
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. |
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