Ich versuche zum ersten Mal, die MVP-Methode mit WinForms zu implementieren.
Ich versuche die Funktion jeder Schicht zu verstehen.
In meinem Programm habe ich eine GUI-Schaltfläche, die beim Klicken ein offenes Dialogfenster öffnet.
Bei Verwendung von MVP verarbeitet die GUI das Schaltflächenklickereignis und ruft dann presenter.openfile () auf.
Sollte das in presenter.openfile () dann das Öffnen dieser Datei an die Modellebene delegieren oder, da keine Daten oder Logik zu verarbeiten sind, einfach auf die Anforderung reagieren und das Fenster openfiledialog öffnen?
Update: Ich habe beschlossen, ein Kopfgeld anzubieten, da ich das Gefühl habe, weitere Unterstützung zu benötigen, und vorzugsweise auf meine spezifischen Punkte unten zugeschnitten, damit ich Kontext habe.
Okay, nachdem ich mich über MVP informiert habe, habe ich beschlossen, die passive Ansicht zu implementieren. Tatsächlich habe ich eine Reihe von Steuerelementen auf einer Winform, die von einem Präsentator verwaltet werden, und dann die Aufgaben, die an die Modelle delegiert wurden. Meine spezifischen Punkte sind unten:
Wenn die Winform geladen wird, muss sie eine Baumansicht erhalten. Habe ich Recht, wenn ich denke, dass die Ansicht daher eine Methode wie: presenter.gettree () aufrufen sollte, die wiederum an das Modell delegiert, das die Daten für die Baumansicht abruft, erstellt und konfiguriert und an die zurückgibt Moderator, der wiederum an die Ansicht übergeht, die sie dann beispielsweise beispielsweise einem Panel zuweist?
Wäre dies für jede Datensteuerung auf der Winform dasselbe, da ich auch eine Datagrid-Ansicht habe?
Meine App verfügt über eine Reihe von Modellklassen mit derselben Assembly. Es unterstützt auch eine Plugin-Architektur mit Plugins, die beim Start geladen werden müssen. Würde die Ansicht einfach eine Präsentationsmethode aufrufen, die wiederum eine Methode aufruft, die die Plugins lädt und die Informationen in der Ansicht anzeigt? Welche Ebene würde dann die Plugin-Referenzen steuern? Würde die Ansicht Verweise auf sie oder den Moderator enthalten?
Bin ich zu Recht der Meinung, dass die Ansicht alle Aspekte der Präsentation behandeln sollte, von der Farbe des Baumansichtsknotens bis zur Größe des Datagrids usw.?
Ich denke, dass sie meine Hauptanliegen sind und wenn ich verstehe, wie der Fluss für diese sein sollte, denke ich, dass es mir gut gehen wird.
Antworten:
Dies ist meine bescheidene Einstellung zu MVP und Ihren spezifischen Problemen.
Erstens ist alles, mit dem ein Benutzer interagieren oder nur angezeigt werden kann, eine Ansicht . Die Gesetze, Verhaltensweisen und Eigenschaften einer solchen Ansicht werden durch eine Schnittstelle beschrieben . Diese Schnittstelle kann mithilfe einer WinForms-Benutzeroberfläche, einer Konsolen-Benutzeroberfläche, einer Web-Benutzeroberfläche oder gar keiner Benutzeroberfläche implementiert werden (normalerweise beim Testen eines Präsentators). Die konkrete Implementierung spielt keine Rolle, solange sie den Gesetzen der Ansichtsoberfläche entspricht .
Zweitens wird eine Ansicht immer von einem Präsentator gesteuert . Die Gesetze, Verhaltensweisen und Eigenschaften eines solchen Präsentators werden auch durch eine Schnittstelle beschrieben . Diese Schnittstelle hat kein Interesse an der konkreten Ansichtsimplementierung, solange sie den Gesetzen ihrer Ansichtsschnittstelle entspricht.
Drittens , da ein Präsentator seine Ansicht kontrolliert, um Abhängigkeiten zu minimieren, ist es wirklich kein Vorteil, wenn die Ansicht überhaupt etwas über seinen Präsentator weiß. Es gibt einen vereinbarten Vertrag zwischen dem Präsentator und der Ansicht, der von der Ansichtsoberfläche angegeben wird.
Die Implikationen von Third sind:
Für Ihr Problem könnte das Obige in etwas vereinfachtem Code so aussehen:
Darüber hinaus habe ich normalerweise eine Basisschnittstelle
IView
, in der ich dieShow()
Eigentümeransicht oder den Ansichtstitel, von dem meine Ansichten normalerweise profitieren, aufbewahre.Auf Ihre Fragen:
1. Wenn die Winform geladen wird, muss sie eine Baumansicht erhalten. Habe ich Recht, wenn ich denke, dass die Ansicht daher eine Methode wie: presenter.gettree () aufrufen sollte, die wiederum an das Modell delegiert, das die Daten für die Baumansicht abruft, sie erstellt und konfiguriert und an die zurückgibt Moderator, der wiederum an die Ansicht übergeht, die sie dann beispielsweise beispielsweise einem Panel zuweist?
2. Wäre dies für jede Datensteuerung auf der Winform gleich, da ich auch eine Datagrid-Ansicht habe?
3. Meine App verfügt über eine Reihe von Modellklassen mit derselben Assembly. Es unterstützt auch eine Plugin-Architektur mit Plugins, die beim Start geladen werden müssen. Würde die Ansicht einfach eine Präsentationsmethode aufrufen, die wiederum eine Methode aufruft, die die Plugins lädt und die Informationen in der Ansicht anzeigt? Welche Ebene würde dann die Plugin-Referenzen steuern? Würde die Ansicht Verweise auf sie oder den Moderator enthalten?
4. Habe ich Recht, wenn ich denke, dass die Ansicht alle Aspekte der Präsentation behandeln sollte, von der Farbe des Baumansichtsknotens bis zur Größe des Datagrids usw.?
Was ist mit Daten für angeklickte Knoten?
5. Wenn ich beim Klicken auf die Treenodes den spezifischen Knoten an den Präsentator weiterleiten sollte, würde der Präsentator dann herausfinden, welche Daten er benötigt, und dann das Modell nach diesen Daten fragen, bevor er sie wieder der Ansicht präsentiert?
quelle
Der Präsentator, der die gesamte Logik in der Ansicht enthält, sollte auf die Schaltfläche reagieren, auf die geklickt wird, wie @JochemKempe sagt . In der Praxis ruft der Ereignishandler für Schaltflächenklicks auf
presenter.OpenFile()
. Der Präsentator kann dann bestimmen, was zu tun ist.Wenn der Benutzer eine Datei auswählen muss, ruft er die Ansicht (über eine Ansichtsoberfläche) zurück und lässt die Ansicht, die alle technischen Details der Benutzeroberfläche enthält, die anzeigen
OpenFileDialog
. Dies ist eine sehr wichtige Unterscheidung, da der Präsentator keine Vorgänge ausführen darf, die an die verwendete UI-Technologie gebunden sind.Die ausgewählte Datei wird dann an den Präsentator zurückgegeben, der seine Logik fortsetzt. Dies kann jedes Modell oder jeden Dienst betreffen, der die Verarbeitung der Datei übernehmen soll.
Der Hauptgrund für die Verwendung eines MVP-Musters imo besteht darin, die UI-Technologie von der Ansichtslogik zu trennen. Somit orchestriert der Präsentator die gesamte Logik, während die Ansicht sie von der UI-Logik trennt. Dies hat den sehr schönen Nebeneffekt, dass der Präsentator vollständig testbar ist.
Update: Da der Präsentator die Verkörperung der Logik ist, die in einer bestimmten Ansicht gefunden wird , ist die Ansicht-Präsentator-Beziehung IMO eine Eins-zu-Eins-Beziehung. Für alle praktischen Zwecke interagiert eine Ansichtsinstanz (z. B. ein Formular) mit einer Präsentatorinstanz, und eine Präsentatorinstanz interagiert nur mit einer Ansichtsinstanz.
In meiner Implementierung von MVP mit WinForms interagiert der Präsentator jedoch immer mit der Ansicht über eine Schnittstelle, die die UI-Fähigkeiten der Ansicht darstellt. Es gibt keine Einschränkung, welche Ansicht diese Schnittstelle implementiert. Daher können verschiedene "Widgets" dieselbe Ansichtsschnittstelle implementieren und die Präsentatorklasse wiederverwenden.
quelle
Der Präsentator sollte auf Anfrage reagieren und das von Ihnen vorgeschlagene OpenFiledialog-Fenster anzeigen. Da für das Modell keine Daten erforderlich sind, kann und sollte der Präsentator die Anforderung bearbeiten.
Angenommen, Sie benötigen die Daten, um einige Entitäten in Ihrem Modell zu erstellen. Sie können den Stream entweder an die Zugriffsebene übergeben, auf der Sie eine Methode zum Erstellen von Entitäten aus dem Stream haben. Ich empfehle jedoch, das Parsen der Datei in Ihrem Präsentator durchzuführen und einen Konstruktor oder eine Methode zum Erstellen pro Entität in Ihrem Modell zu verwenden.
quelle