Announcement

Collapse
No announcement yet.

MVP mal wieder

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • MVP mal wieder

    Hallo alle zusammen,

    Ich brauch mal wieder euren werten Rat. Entweder bin ich schon wieder zu restriktiv oder ich verstehe etwas noch nicht ganz.
    Folgendes Szenario:

    [highlight=c#]
    public class Module
    {
    public String Description { get; set; }
    public IList<Teststep> Teststeps { get; set; }
    }

    public class Teststep
    {
    public double UpperLimit { get; set; }
    public double LowerLimit { get; set; }
    }
    [/highlight]

    Eine Instanz der Klasse Module würde ich nun gerne in einem Fenster darstellen. Es soll eine Windows Forms Anwendung werden. Ich hatte mir vorgestellt im oberen Bereich ein Panel für die Properties des Moduls und darunter ein DataGridView für die Teststeps. Auf DataBinding möchte ich gerne verzichten. Das ist mir nicht flexibel genug.

    Also definiere ich folgende Interfaces:

    [highlight=c#]
    public interface IModuleView
    {
    String DescriptionText { get; set; }

    ITeststepView CreateTeststepView();
    void AddTeststepView(ITeststepView view);
    }

    public interface ITeststepView
    {
    String UpperLimit { get; set; }
    String LowerLimit { get; set; }
    }
    [/highlight]

    Hierzu meine Fragen:

    1. Ist die Vorgehensweise mit dem Create/Add-TeststepView richtig? Meine Lösung basiert darauf, dass der Presenter ja nicht entscheiden kann welchen View er instantiieren muss. Also fragt er den ModuleView was er als View für den Teststep verwenden soll.

    2. Wie reiche ich das eigentliche Objekt durch? Soll ich IModuleView noch eine Property hinzufügen? So in etwa?

    [highlight=c#]
    public interface IModuleView
    {
    ...
    Module ShownModule { get; set; }
    ...
    }
    [/highlight]

    Das würde allerdings wieder das Prinzip verletzen, dass der View nichts von seinem Model weiss.
    Eine zweite Alternative wäre es den Presenter zur Laufzeit per Dependency Injection zu erzeugen und diesem im Konstruktor das Modul-Objekt mitzugeben.
    Die dritte Alternative wäre es dem Presenter eine Schnittstelle (z.B. IModuleDal) mitzugeben und dem View nur die Id des anzuzeigenden Moduls mitzugeben. So in etwa:

    [highlight=c#]
    public interface IModuleView
    {
    ...
    Int64 ShownModuleId { get; set; }
    ...
    }
    [/highlight]

    Der Presenter würde daraufhin ein Query auf die Datenbank absetzen und sich das Objekt selbst holen. Da ich allerdings das Objekt normalerweise schon habe (es gibt so etwas wie einen Open Dialog) macht es imho nicht viel Sinn dort noch einen Datenbank Zugriff zu fahren. Das Problem stellt sich ausserdem bei den Teststeps auch wieder, da ich die Teststeps auf jeden Fall alle habe sobald das Modul aus der DB geladen wurde

    Das ganze bereitet mir schon seit einigen Wochen kopfzerbrechen und ich komme einfach nicht dahinter wie ich das am Besten löse.

    Wahrscheinlich bin ich einfach wieder zu ehrgeizig und suche nach der zu perfekten Lösung Mich würde allerdings eure Meinung zu dem Thema interessieren.

    Vielen Dank schon mal an alle!!!

    Gruß,
    fanderlf

  • #2
    1. Ist die Vorgehensweise mit dem Create/Add-TeststepView richtig.
    Richtig .. falsch. Die Sache ist wohl weder schwarz noch weiß sondern sehr grau
    Ich würde es aber eher anders machen.

    Meine Lösung basiert darauf, dass der Presenter ja nicht entscheiden kann welchen View er instantiieren muss. Also fragt er den ModuleView was er als View für den Teststep verwenden soll.
    Nach meinem dafürhalten sollte ein Presenter nur sein eigenen View kennen. Auch wenn du dem Presenter die Aufgabe des Instantiierens des fremden Views abgenommen und dem View übertragen hast so hast du doch ein Info an den Presenter veröffentlicht die er eigentlich nicht wissen sollte nämlich das IModuleView aus ITeststepViews besteht. Das Zusammenspiel mehrerer View-Presenter Paare ist eigentlich ein oberhalb des eigentlich MVP Pattern liegendes Problem und sollte auch außerhalb gelöst werden. Bei mir heißt diese Klasse üblicherweise Controller. Diese kennt das Model erzeugt daraus die benötigten Views und die Presenter der Views holen sich wiederum im folgenden dann die benötigten Modelklassen vom Controller und schieben die Daten dieser Klasse in ihren View. Ich persönlich halte es nicht für schlimm das der View etwas vom Model weiß benutze aber selbst einen eher MVVMartigen Ansatz wodurch das sogar eher gewünscht ist. Um das Model in den Presenter zu bekommen kann DI (wie du selbst angemerkt hast) hilfreich sein.

    Comment


    • #3
      OK an so einen Ansatz hab ich heute morgen auch schon gedacht.

      Ich würd dann praktisch hinter meiner Form wieder so etwas wie einen "Presenter" (das was Du Controller bezeichnet hast) hinterlegen. Der dann die Abhängigkeiten zwischen den einzelnen Views managed.
      Der positive Nebeneffekt wäre dann bei mir, dass ich die Forms nicht mehr in derselben Assembly habe wie die Präsentationslogik. Ich glaube das werde ich mal versuchen.

      Jetzt muss ich mir nur noch überlegen wie ich per DI das Model in den Presenter bekomme ohne das Object wieder über den View schieben zu müssen.

      Wäre es eventuell sinnvoll für die IList<Teststep> einen eigenen View zu erstellen? Der View müsste die Positionierung der Elemente verwalten, weil diese nicht beliebig ist.
      Zuletzt editiert von fanderlf; 03.11.2009, 12:08.

      Comment

      Working...
      X