Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   MVC -- Daten-Validierung, komplexe Models und deren Darstellung (https://www.delphipraxis.net/163819-mvc-daten-validierung-komplexe-models-und-deren-darstellung.html)

s.h.a.r.k 17. Okt 2011 19:59

MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
So, habe nun doch noch ein paar Fragen zum MVC-Pattern :) Im Allgemeinen habe ich das ganze eigentlich durchdrungen, nur habe ich da hin und wieder doch Probleme. Zum einen mit der Validierung der eingegebenen Daten. An der Stelle finde ich es immer ganz schick, wenn die eingegebenen Daten live validiert und entsprechende Fehler in einer Liste ausgegeben werden, evtl. direkt nebem dem Control, in dem falsche Daten stehen. Gut, dieser Gedanke impliziert, dass bei jeder Änderung an der Eingabe dem Controller mitgeteilt wird, dass Daten auf der View aktualisiert werden und dieser die Daten zu validieren hat. Passt alles, so können diese ins Model übernommen werden. Oder sollte die Validierung vielleicht ins Model? Aber wie sollte die Validierung ablaufen? Im Setter? Die nächste Frage wäre dann, wo werden die Fehlermeldungen gespeichert? In einer Liste? Oder werden beim Setzen der Werte Exception geworfen? An der Stelle wäre es eben interessant, was State of the Art ist bzw. wie ihr das handhabt.

Gut, nun zu den komplexeren Models: es gibt ja beliebige Abhängigkeiten von Models untereinander -- nur um ein kleines Beispiel zu nennen: ein Schüler ist in einer Klasse, die einen Lehrer hat. So... Nun besteht doch das Problem, dass eine View von zwei Models abhängt, zumal eine View für beliebig viele Models da sein kann -- sowas hängt ja auch ungemein von der erwünschten Usability ab. Wenn ich hier von einer View rede meine ich explizit ein Control und nicht gleich eine ganze Form! Daher sehe ich das MVC-Pattern eher als MVsC -> Model, Views, Control, d.h. dass ich für ein Model mehrere Views bzw. Model-übergreifende Views haben kann -- aber wie handle ich sowas dann?

Also, auf gehts :stupid:

webcss 17. Okt 2011 20:19

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Zitat:

Zitat von s.h.a.r.k (Beitrag 1130931)
..., wenn die eingegebenen Daten live validiert und entsprechende Fehler in einer Liste ausgegeben werden, evtl. direkt nebem dem Control, in dem falsche Daten stehen. Gut, dieser Gedanke impliziert, dass bei jeder Änderung an der Eingabe dem Controller mitgeteilt wird, dass Daten auf der View aktualisiert werden und dieser die Daten zu validieren hat.... Oder sollte die Validierung vielleicht ins Model? Aber wie sollte die Validierung ablaufen? Im Setter?

Die Validierung sollte immer "so nah" wie möglich an den Daten passieren, also im Setter des Models. Via Observer Pattern hast Du die Möglichkeit, Fehler "soft" via Statusmeldung oder bubble hint oder Farbänderung des Controls etc. zu signalisieren. Spätestens sollte eine Validierung vor dem speichern durchgeführt werden.
Noch mehr "live" ist die Validierung bzw. Filterung der Eingabe, z.B. keine Buchstaben, wo nur Zahlen gewünscht sind (MaskedEdit oder Key Preview).
Zitat:

Zitat von s.h.a.r.k (Beitrag 1130931)
Gut, nun zu den komplexeren Models: es gibt ja beliebige Abhängigkeiten von Models untereinander ... d.h. dass ich für ein Model mehrere Views bzw. Model-übergreifende Views haben kann -- aber wie handle ich sowas dann?

Auch hier ist das Observer Pattern Dein Freund, Änderungen am Model werden direkt durch alle observierenden Controls reflektiert.

Sir Rufo 17. Okt 2011 20:34

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Mir gefällt da die Methode von DSharp wesentlich besser und die Verbindung zwischen dem Model und der View via Binding zu realisieren.
Der Validator sitzt dabei im Binding.

stahli 17. Okt 2011 21:36

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Ok, das Thema interessiert mich ja auch schon länger. Das Resultat meiner Versuche sind die odControls.

Über die ganzen Patterns habe ich auch einiges gelesen, aber das ist insgesamt doch recht schwammig (liegt ja in der Natur der Sache).
Ich gehe davon aus, dass häufig nicht mal jeder das gleiche meint, selbst wenn gemeinsam diskutiert wird.

Daher habe ich mich selbst herangetastet und folgende Lösung:

Die Daten + Geschäftslogik liegen in Objekten, die wieder andere Objekte enthalten können. Das oberste Objekt beeinhaltet also letztlich alle Daten (kennt aber nur seine direkten SubObjekte) und sämtliche Geschäftslogik.

Meine Controls sind von Standardcontrols abgeleitet, dem ein "Controler" hinzugefügt ist. Dem Objekt kann ein Datenobjekt und ein PropertyName zugewiesen werden.

Alle Controler werden beim Erzeugen in einer Liste eingetragen und beim Zerstören wieder daraus gelöscht.

Erfolgt in einem Datenobjekt eine Änderung, wird ein Timer mit einer kleinen Verzögerung gestartet. Erfolgt eine weitere Änderung wird der Timer neu gestartet. Erfolgte einige Zeit keine weitere Änderung, feuert der Timer und informiert alle registrierten Controler über eine Änderung. Diese rufen für ihr Owner-Control Invalidate auf.

Wenn das Control sichtbar ist bzw. das nächste mal angezeigt wird, holt es sich den aktuellen Wert von seinem Controler ab (dem Control ist es dabei egal, was das für ein Objekt ist).
Wird der Wert in dem Control geändert (z.B. in TodEdit) übergibt dieses den neuen Wert an sein Control, das den Wert "in das Objekt schreibt".

Eine Validierung führe ich i.d.R. erst im Setter bzw. der Geschäftslogik durch.

Formulare erhalten auch einen Controler, so dass ein Formular für ein Objekt und seine Unterobjekte "personalisiert" wird.

Ein Datenobjekt kann seine Daten speichern und seine Unterobjekte veranlassen, das ebenfalls zu tun.
Beim Laden von Daten werden Objekte (z.B. in Listen) vorher automatisch erzeugt.
Darum muss man sich also nicht mehr kümmern.

In welches Pattern das Ganze nun passt (und ob überhaupt) ist mir noch nicht ganz klar geworden.

Wichtig ist mir, dass ich komplexe Projekte mit möglichst wenig Aufwand und möglichst flexibel erstellen kann. Die Trennung von Daten+Geschäftslogik von der GUI will ich nicht mehr missen.
Was ich vermeiden möchte ist, für jedes Projekt von Hand neue Datenobjekte und Controler zu erstellen.

Viel lieber möchte ich ein Framework haben, in dem ich in einfacher Weise eine (auch komplexe) Datenstruktur definieren kann, Formulare zusammenklicke und beide Ebenen im Designer verbinde.
Dann ist EIGENTLICH nur noch die Geschäftslogik zu programmieren.


Ich kann anhand Eurer Diskussionen noch nicht recht nachvollziehen, wie nah oder weit wir voneinander entfernt sind. Zumindest das ANLIEGEN düfte das gleiche sein.


Im Moment habe ich keine Datenbankverbindung. Das habe ich zwar vor, aber noch keine genaue Vorstellung der Realisierung.


Vielleicht kann sich ja mal ein allgemein zugängliches Framework heraus kristallisieren, das die Arbeit mit Delphi noch weiter erleichert.
Die grundlegenden Fragen sind dabei sicher, ob die GUI leicht austauschbar sein soll und ob und in welcher Form eine Datenbank benutzt werden soll.


Grundsätzlich möchte ich anregen, bei Diskussionen nicht zu viele "wohlklingende Fachbegriffe" zu benutzen, da u.U. nicht jeder das gleiche darunter versteht...

s.h.a.r.k 17. Okt 2011 21:37

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Genau das, was Sir Rufo hier anspricht, ist grob mein Problem bie der Validierung. Denn das Model kann durchaus asynchron zur View laufen, wenn in der View falsche Daten stehen und diese somit nicht aufs Model übernommen werden. Ebenso will ich evtl. auch einen "Zurücksetzen"-Button haben, der nicht das Model neu aus der DB lädt, oder einen Abbrechen-Button, der keinerlei Änderungen der aktuellen Dialogs übernimmt. Würde ich alle Änderungen live ins Model übernehmen, habe ich dann ja mehr oder weniger Probleme... An der Stelle hat das dann nichts mehr mit Usability zu tun.

Das ist halt die Sicht der GUI-Designers. Bisher habe ich dafür noch keine gute Methode gefunden, außer die View mit den Daten aus einem Model zu füllen und dann ein neues Model für die Validierung zu erstellen, denn darin ist der Validierungs-Code bzw. die Constraints -- ob das nun in einer Validate-Methode oder in den Settern implementiert ist, ist zunächst mal egal.

Sir Rufo 17. Okt 2011 21:48

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Aber genau das geht mit DSharp. Das Bindung kann dort auch explizit erfolgen, also nur auf ausdrücklichen Wunsch.
Die Validierung bleibt aber bestehen ;)

s.h.a.r.k 17. Okt 2011 22:05

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Hm, habe mir das mit den Bindings noch nicht so recht angeschaut. Sollte ich bei Zeit echt mal tun... Befürchte dahingehend aber irgendwie, dass mir Flexibilität bzgl. besonderer GUI-Features, wie z.B. diese Live-Validierung, verloren geht... Aber ich lasse mich gerne eines bessere belehren :stupid:

webcss 17. Okt 2011 22:07

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Zitat:

Zitat von s.h.a.r.k (Beitrag 1130950)
Genau das, was Sir Rufo hier anspricht, ist grob mein Problem bie der Validierung. Denn das Model kann durchaus asynchron zur View laufen, wenn in der View falsche Daten stehen und diese somit nicht aufs Model übernommen werden. Ebenso will ich evtl. auch einen "Zurücksetzen"-Button haben, der nicht das Model neu aus der DB lädt, oder einen Abbrechen-Button, der keinerlei Änderungen der aktuellen Dialogs übernimmt. Würde ich alle Änderungen live ins Model übernehmen, habe ich dann ja mehr oder weniger Probleme... An der Stelle hat das dann nichts mehr mit Usability zu tun.

Und genau das ist der Grund für die Existenz von Pattern: Sie beschreiben lediglich in einer Art Metasprache die Lösung eines bestimmten Problems, aus der Erfahrung vieler Mannjahre heraus.

Für dieses Problem gibt es z.B. das Memento Pattern. damit erstellst Du eine exakte Arbeitskopie der zu bearbeitenden Daten -> im Model. Wenn der Controller/Presenter den Befehl erhält "Alles gut, speichern" wird diese Kopie validiert und in die Datenschicht übertragen (oder Fehler reklamiert).
Kommt der Befehl "Vergiss es, wollte nur spielen" wird die Kopie einfach gelöscht und nix passiert weiter.

stahli 17. Okt 2011 22:09

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Weil es gerade zum Thema passt: "Refactoring / Variable definieren" löst das ganz hübsch ;-)

s.h.a.r.k 17. Okt 2011 22:14

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Zitat:

Zitat von stahli (Beitrag 1130958)
Weil es gerade zum Thema passt: "Refactoring / Variable definieren" löst das ganz hübsch ;-)

Habs in Eclipse schon wesentlich schöner gesehen ;) Sogar mit passender Fehlerbeschreibung. Unter Visual Studio kannst beim Error Insight sogar Verbesserungsvorschläge auswählen.

Zitat:

Zitat von webcss (Beitrag 1130955)
Und genau das ist der Grund für die Existenz von Pattern: Sie beschreiben lediglich in einer Art Metasprache die Lösung eines bestimmten Problems, aus der Erfahrung vieler Mannjahre heraus.

Das ist mir ja eben bewusst. Mir ist aber auch bewusst, dass ich entscheidende Dinge einfach noch nicht weiß, und ich denke, dass es hier vielen so geht. Daher habe ich den Thread eröffnet, in der Hoffnung, dass auch andere etwas davon haben :) Danke für den Hinweis auf das Pattern -- kannte das noch nicht ;)

Was mir nur häufig fehlt ist eben ein konkretes Programmierbeispiel bzw. eigentlich Beispiele, da man ein Pattern ja auf mehrere Arten und Weisen interpretieren und umsetzen kann. Daher bin ich auch gerne offen für Code, über den diskutiert werden kann :)

Stevie 17. Okt 2011 22:20

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Ich geh mal auf DSharp ein:

Es gibt ja unterschiedliche Arten von Validierung, formale (im Sinne von, Name muss mindestens 3 Zeichen lang sein), inhaltliche (Postleitzahl muss gültig sein) und komplexe (wenn ich als Zahlungsmethode Visa auswähle müssen die Kreditkarten Daten stimmen). Die ersten beiden können noch vom Binding selber abgeprüft werden, indem man ne ValidationRule angibt. Komplexe (und teilweise auch inhaltliche) müssen in der Regel vom Viewmodel (ich bleib hier mal MVVM Pattern) durchgeführt werden, weil dort die unterschiedlichen Eigenschaften zusammen kommen, die für eine Validierung notwendig sind.

Das alles ist ohne weiteres möglich (Demo zu einigen unterschiedlichen Validierungsmöglichkeiten gibts im repository). Bei allen Arten der Validierung wird aber auf jeden Fall verhindert, dass irgendwelche nicht validierten Werte in das Viewmodel (und damit ins Model) gelangen (außer du machst es explizit durch den Aufruf der UpdateSource Methode).

Ziel der ganzen Übung ist es ja, die Oberfläche so dumm wie möglich zu gestalten, so dass sie nur als User Interface dient und jegliche Logik in der Schicht darunter steckt. Somit kannst du letzlich ganze Funktionstests automatisiert durchführen (und ich rede nicht von Dingen wie TestComplete oder so) ohne die GUI zu benötigen.

Bei Fragen zu DSharp direkt oder generell zu verwandten Themen steh ich auch gern per PM zur Verfügung.

@Roter Kasten: Memento unterstützt DSharp auch, es gibt eine Basis ViewModel Klasse, in der das direkt implementiert ist.

webcss 18. Okt 2011 06:01

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Zitat:

Zitat von s.h.a.r.k (Beitrag 1130961)
Das ist mir ja eben bewusst. Mir ist aber auch bewusst, dass ich entscheidende Dinge einfach noch nicht weiß, und ich denke, dass es hier vielen so geht
....
Was mir nur häufig fehlt ist eben ein konkretes Programmierbeispiel bzw. eigentlich Beispiele, da man ein Pattern ja auf mehrere Arten und Weisen interpretieren und umsetzen kann. Daher bin ich auch gerne offen für Code, über den diskutiert werden kann :)

Kenne ich und ist sehr blöd. Es gibt viele Seiten zu dem Thema, allerdings wenige für Delphi. Einige, die mir geholfen haben:
sourcemaking.com/design_patterns
building-a-composite-application-framework.aspx
model-view-presenter-mvp-design-pattern-close-look-part-2-passive-view.aspx

Zitat:

Zitat von s.h.a.r.k (Beitrag 1130961)
Danke für den Hinweis auf das Pattern -- kannte das noch nicht ;)

Ist z.B. auch in der unit classes vorhanden. TMemento implementiert dieses Verhalten für TPersistent (Nachfahren).

Stevie 18. Okt 2011 07:10

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Zitat:

Zitat von webcss (Beitrag 1130980)
Zitat:

Zitat von s.h.a.r.k (Beitrag 1130961)
Danke für den Hinweis auf das Pattern -- kannte das noch nicht ;)

Ist z.B. auch in der unit classes vorhanden. TMemento implementiert dieses Verhalten für TPersistent (Nachfahren).

Kann es sein, dass du TRecall meinst? Von TMemento hab ich noch nie was gehört (und ist auch nirgendwo im Delphi Source vorhanden)

webcss 18. Okt 2011 07:17

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Zitat:

Zitat von Stevie (Beitrag 1130982)
Kann es sein, dass du TRecall meinst? Von TMemento hab ich noch nie was gehört (und ist auch nirgendwo im Delphi Source vorhanden)

Uuups, ja genau, ich meine natürlich TRecall... :oops:

mquadrat 18. Okt 2011 09:22

AW: MVC -- Daten-Validierung, komplexe Models und deren Darstellung
 
Die Validierung lässt sich selten eindeutig zuordnen. Im Web - wo man nicht mal eben dem Model oder dem Controller sagen kann, dass jemand ein Zeichen eingetippt hat - wird die Validierung meist direkt im View vorgenommen.

Wenn man keine Bindings benutzt würde ich in Delphi den selben weg gehen. Also entweder eine Klasse, die sich an die entsprechenden Events der Controls anhängt oder eben die Controls erweitern / dekorieren. Mit Bindings die simplen Validierungen in den Bindings und die komplexen im Modell. Validierung der komplexen Bedingungen im View-Model könnte daran scheitern, dass nicht alle der benötigten Informationen public sind.


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