Ich habe in der Vergangenheit MVP und MVC verwendet, und ich bevorzuge MVP, da es meiner Meinung nach den Ausführungsfluss so viel besser steuert.
Ich habe meine Infrastruktur (Datenspeicher- / Repository-Klassen) erstellt und verwende sie problemlos, wenn ich Beispieldaten fest codiere. Jetzt gehe ich auf die GUI und bereite mein MVP vor.
Abschnitt a
Ich habe gesehen, dass MVP die Ansicht als Einstiegspunkt verwendet, das heißt, in der Konstruktormethode für Ansichten wird der Presenter erstellt, wodurch wiederum das Modell erstellt wird und Ereignisse nach Bedarf verkabelt werden.
Ich habe den Presenter auch als Einstiegspunkt gesehen, an dem eine Ansicht, ein Modell und ein Presenter erstellt werden. Dieser Presenter erhält dann in seinem Konstruktor eine Ansicht und ein Model-Objekt, um die Ereignisse zu verknüpfen.
Wie in 2, aber das Modell wird nicht an den Präsentator übergeben. Stattdessen ist das Modell eine statische Klasse, in der Methoden aufgerufen und Antworten direkt zurückgegeben werden.
Abschnitt b
In Bezug auf die Synchronisation von Ansicht und Modell habe ich gesehen.
Immer wenn sich ein Wert in der Ansicht ändert, dh ein
TextChanged
Ereignis in .Net / C #. Dies löst eine aus,DataChangedEvent
die in das Modell übertragen wird, um es jederzeit synchron zu halten. Und wenn sich das Modell ändert, dh wenn ein Hintergrundereignis abgehört wird, wird die Ansicht auf die gleiche Weise aktualisiert, indem einDataChangedEvent
. Wenn ein Benutzer Änderungen festschreiben möchte, wird ein Fehler ausgelöstSaveEvent
, der zum Speichern in das Modell übergeht. In diesem Fall ahmt das Modell die Daten der Ansicht nach und verarbeitet Aktionen.Ähnlich wie bei # b1 wird die Ansicht jedoch nicht immer mit dem Modell synchronisiert. Stattdessen
SaveEvent
wird ausgelöst, wenn der Benutzer Änderungen festschreiben möchte, und der Präsentator erfasst die neuesten Details und übergibt sie an das Modell. In diesem Fall kennt das Modell die Ansichtsdaten erst, wenn es darauf reagieren muss. In diesem Fall werden alle erforderlichen Details übergeben.
Abschnitt C
Anzeige von Geschäftsobjekten in der Ansicht, dh ein Objekt (MyClass) nicht primitiven Daten (int, double)
Die Ansicht verfügt über Eigenschaftsfelder für alle Daten, die als Domänen- / Geschäftsobjekte angezeigt werden. B.
view.Animals
macht eineIEnumerable<IAnimal>
Eigenschaft verfügbar, obwohl die Ansicht diese in einem TreeView zu Knoten verarbeitet. Dann würde es für das ausgewählte TierSelectedAnimal
alsIAnimal
Eigentum aussetzen .Die Ansicht verfügt nicht über Kenntnisse zu Domänenobjekten. Sie macht die Eigenschaften nur für die in Primitive / Framework (.Net / Java) enthaltenen Objekttypen verfügbar. In diesem Fall übergibt der Präsentator ein Adapterobjekt an das Domänenobjekt. Der Adapter übersetzt dann ein bestimmtes Geschäftsobjekt in die Steuerelemente, die in der Ansicht sichtbar sind. In diesem Fall muss der Adapter Zugriff auf die tatsächlichen Steuerelemente in der Ansicht haben, und nicht auf eine beliebige Ansicht, damit eine engere Verbindung hergestellt wird.
Abschnitt D
Mehrere Ansichten zum Erstellen eines einzelnen Steuerelements. Dh Sie haben eine komplexe Ansicht mit einem einfachen Modell wie das Speichern von Objekten verschiedener Typen. Sie könnten ein Menüsystem an der Seite haben, bei jedem Klick auf ein Element werden die entsprechenden Steuerelemente angezeigt.
Sie erstellen eine große Ansicht, die alle einzelnen Steuerelemente enthält, die über die Ansichtsschnittstelle verfügbar gemacht werden.
Sie haben mehrere Ansichten. Sie haben eine Ansicht für das Menü und ein leeres Bedienfeld. Diese Ansicht erstellt die anderen erforderlichen Ansichten, zeigt sie jedoch nicht an (visible = false). Diese Ansicht implementiert auch die Benutzeroberfläche für jede darin enthaltene Ansicht (z. B. untergeordnete Ansichten), sodass sie einem Präsentator angezeigt werden kann. Das leere Feld ist mit anderen Ansichten (
Controls.Add(myview)
) und ((myview.visible = true
) gefüllt . Die in diesen "untergeordneten" Ansichten ausgelösten Ereignisse werden von der übergeordneten Ansicht verarbeitet, die das Ereignis wiederum an den Präsentator weiterleitet, und umgekehrt, um Ereignisse wieder an untergeordnete Elemente weiterzuleiten.Jede Ansicht, sei es die übergeordnete Hauptansicht oder eine kleinere untergeordnete Ansicht, ist mit einem eigenen Präsentator und Modell verbunden. Sie können ein Ansichtssteuerelement einfach in ein vorhandenes Formular einfügen, und die Funktionalität ist bereit. Sie müssen lediglich hinter den Kulissen eine Verbindung zu einem Präsentator herstellen.
Abschnitt E
Sollte alles über eine Schnittstelle verfügen, wirkt sich dies auf die Vorgehensweise des MVP in den obigen Beispielen aus, da diese möglicherweise nicht kompatibel sind.
Alles hat eine Oberfläche, die Ansicht, Presenter und Modell. Jede davon hat dann offensichtlich eine konkrete Umsetzung. Auch wenn Sie nur eine konkrete Ansicht, ein Modell und einen Präsentator haben.
Die Ansicht und das Modell haben eine Schnittstelle. Dadurch können sich die Ansichten und Modelle unterscheiden. Der Präsentator erstellt / erhält eine Ansicht und ein Modell von Objekten und dient nur dazu, Nachrichten zwischen ihnen zu übertragen.
Nur die Ansicht hat eine Schnittstelle. Das Modell verfügt über statische Methoden und wird nicht erstellt. Daher ist keine Schnittstelle erforderlich. Wenn Sie ein anderes Modell wünschen, ruft der Präsentator einen anderen Satz statischer Klassenmethoden auf. Da das Modell statisch ist, hat es keine Verbindung zum Präsentator.
Persönliche Gedanken
Von all den verschiedenen Variationen, die ich vorgestellt habe (die meisten habe ich wahrscheinlich in irgendeiner Form verwendet), von denen ich sicher bin, dass es mehr gibt. Ich bevorzuge A3, da die Geschäftslogik außerhalb von MVP wiederverwendbar bleibt, B2 für weniger Datenduplizierung und weniger ausgelöste Ereignisse. C1 Wenn Sie keine andere Klasse hinzufügen, stellen Sie sicher, dass eine kleine Menge nicht testbarer Logik in eine Ansicht eingefügt wird (wie ein Domänenobjekt visualisiert wird), dies kann jedoch durch Code überprüft oder einfach in der Anwendung angezeigt werden. Wenn die Logik komplex wäre, würde ich einer Adapterklasse zustimmen, aber nicht in allen Fällen. Für Abschnitt D denke ich, dass D1 eine Ansicht erstellt, die zumindest für ein Menübeispiel zu groß ist. Ich habe vorher D2 und D3 benutzt. Das Problem mit D2 ist, dass Sie am Ende viel Code schreiben müssen, um Ereignisse vom und zum Präsentator in die richtige untergeordnete Ansicht zu leiten. Jede neue Steuerung benötigt mehr Kabel, um den einzelnen Presenter zu unterstützen. D3 ist meine bevorzugte Wahl, fügt aber noch weitere Klassen als Präsentatoren und Modelle hinzu, um mit der Ansicht umzugehen, selbst wenn die Ansicht sehr einfach ist oder nicht wiederverwendet werden muss. Ich denke, eine Mischung aus D2 und D3 ist am besten auf die Umstände. In Bezug auf Abschnitt E denke ich, dass alles, was eine Schnittstelle hat, überflüssig sein könnte. Ich mache dies bereits für Domänen- / Geschäftsobjekte und sehe oft keinen Vorteil im "Design", aber es hilft beim Verspotten von Objekten in Tests. Persönlich würde ich E2 als klassische Lösung sehen, obwohl ich E3 in 2 Projekten gesehen habe, an denen ich zuvor gearbeitet habe. Ich denke, eine Mischung aus D2 und D3 ist am besten auf die Umstände. In Bezug auf Abschnitt E denke ich, dass alles, was eine Schnittstelle hat, überflüssig sein könnte. Ich mache dies bereits für Domänen- / Geschäftsobjekte und sehe oft keinen Vorteil im "Design", aber es hilft beim Verspotten von Objekten in Tests. Persönlich würde ich E2 als klassische Lösung sehen, obwohl ich E3 in 2 Projekten gesehen habe, an denen ich zuvor gearbeitet habe. Ich denke, eine Mischung aus D2 und D3 ist am besten auf die Umstände. In Bezug auf Abschnitt E denke ich, dass alles, was eine Schnittstelle hat, überflüssig sein könnte. Ich mache dies bereits für Domänen- / Geschäftsobjekte und sehe oft keinen Vorteil im "Design", aber es hilft beim Verspotten von Objekten in Tests. Persönlich würde ich E2 als klassische Lösung sehen, obwohl ich E3 in 2 Projekten gesehen habe, an denen ich zuvor gearbeitet habe.
Frage
Implementiere ich MVP richtig? Gibt es eine richtige Vorgehensweise?
Ich habe Martin Fowlers Arbeit gelesen, die Variationen aufweist, und ich erinnere mich, dass ich als ich anfing, MVC zu machen, das Konzept verstand, aber ursprünglich nicht herausfinden konnte, wo der Einstiegspunkt ist, alles hat seine eigene Funktion, aber was steuert und schafft das Original Satz von MVC-Objekten.