![]() |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
|
AW: Trennung von GUI und Logik, wie geht ihr vor?
Hallo,
vielleicht hilft Dir das Video zu weiteren Erkenntnissen. ![]() Bis bald Chemiker |
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:
MODEL:
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.
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. |
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. |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
|
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
Die Erklärung warum man so was macht ist sicher gut. Allerdings ein Datenmodul als Basis zu nehmen halte ich für ... ... unschön |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
Zitat:
lg, jus |
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: ![]() |
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. |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Setzt den jemand Daniel Teti's
![]() 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 |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
Ob du als Frontend ne Delphianwendung oder Angular Webseite hast, ist dem Ding egal. |
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 |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Machbarkeitsstudie:
![]() |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
Bei MVVM im Web (wie z.b. ![]() |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Für einfache Szenarien funktioniert es aber recht gut.
|
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
Zitat:
Rollo |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Ja, aber nur für die Enterprise
|
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)
|
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
|
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
|
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 |
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.
|
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
gruß K-H |
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. |
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 |
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: |
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 |
AW: Trennung von GUI und Logik, wie geht ihr vor?
... wolltest Du dazu nicht mal ein kleines Video machen?
|
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
ja, will ich immer noch. [OT] Ich schiebe leider noch einen Berg von Aufgaben vor mehr her, bis dafür Zeit ist... [/OT] |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
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. |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
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 |
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? |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
|
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 |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
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... |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
Zitat:
![]() 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. |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
|
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
Also hat das VM ggf. auch intern eine eigenen Datenbestand für die View... |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Zitat:
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 ![]() Das heißt also, dass hier das VM schon mehr Teil der UI als der Businesslogik ist - schaust du hier: ![]() 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). |
AW: Trennung von GUI und Logik, wie geht ihr vor?
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
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:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:16 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-2025 by Thomas Breitkreuz