Ist das eine gute Idee, ViewModel genauso wie Model hinzuzufügen?

16

Ich habe folgende Ebenen in meiner Lösung:

  1. App.Domain
  2. App.Service
  3. App.Core (vielleicht nennst du diese App.DataLayer)
  4. App.Web

Software Design Pattern ist nicht meine Frage, ich habe folgendes Model in Domain

public class Foo {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Ich möchte dieses Modell in der Ansicht verwenden (z. B. auf der Startseite) UND ich möchte es verwenden Id, Name & Value. Wenn ich also ViewModel erstellen möchte, füge ich Folgendes hinzu:

public class FooViewModel {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Also, ist das eine gute Idee? oder einfach Foostatt verwenden FooViewModel?

Mehdi Dehghani
quelle
Ich bin mir nicht sicher, ob ich das verstehe. Wird das Modelnormalerweise nicht an die weitergereicht View? Warum genau müssen Sie die Felder Modelin der neu erstellen View? Wenn die Trennung von Anliegen ein Ziel von ist MVC, unter welchen Umständen würde man das gleiche mit Modelund tun wollen View? Wenn ViewModelbeides ist, warum nicht durch Erweitern / Komponieren von beidem Modelund View?
null
Bitte lesen Sie meine Kommentare zu @ Svidgens Antwort
Mehdi Dehghani
Ich habe ein verwandtes Problem: Bei der Validierung (erforderliches Attribut) der Modelle (und in der Datenbank) müssen bestimmte Werte eingegeben werden. In Ansichten müssen diese Werte jedoch nicht eingegeben werden. Daher muss ich einige Felder aus kopieren die Modelle im Ansichtsmodell - anstatt das Modell direkt zu referenzieren. Allerdings ist dies wahrscheinlich in Ordnung und verletzt DRY in der Tat nicht, da sie zu unterschiedlichen Zwecken dienen (nicht allzu schlimm).
Niico

Antworten:

20

Dies mag zunächst wie eine Verletzung der DRY-Regel aussehen, aber ich würde argumentieren, dass "ähnlicher und sogar identischer Code" nicht unbedingt "Wiederholung" ist, wenn er etwas anderes tut oder sich unabhängig ändern kann. Und im Fall von Ansichtsmodellen definiert der Code, was der "Kunde" sieht, nicht unbedingt die Entitäten und Operationen, über die das Unternehmen spricht. Daher werden dem Client oder der Benutzeroberfläche häufig Modelle angezeigt, die "zufällig identisch" sind. Sie können entweder die Geschäftsregeln und -bedingungen oder die Endbenutzerterminologie unabhängig voneinander ändern.

Also, ich würde die Frage an Sie zurückdrehen. Wenn sich die Domäne ändert, können die Clients der Version 1 die alten Schnittstellen weiterhin verwenden? Werden Sie jemals Begriffe oder Vorgänge in der Benutzeroberfläche anzeigen, die nicht zu den "Kerngeschäftsregeln" gehören? Und umgekehrt?

Diese Art von Fragen im Hinterkopf, wenn die "Funktion" Ihrer Ansicht ausschließlich darin besteht, das zugrunde liegende Domänenmodell zu offenbaren, ja, dies scheint die DRY-Regel zu verletzen.

Bedenken Sie auch, dass das Anzeigen einer Ansicht, die sich bei Modelländerungen natürlicher ändert, auch in einigen Sprachen mit Elementattributen und Reflexion möglich ist. (Oder mit weniger Wiederholungen durch andere Meisterleistungen der Klugheit ... Aber "Klugheit" kann die Wiederholung, die sie Ihnen erspart, oft nicht rechtfertigen.)

Svidgen
quelle
Nizza erwähnte Notizen (stimme dafür ab), wie ich als Kommentar zu der vorherigen Antwort sagte, ich spreche von Allzweck, Bildgebung, vielleicht einige Tage später habe ich beschlossen, ein neues Feld / eine neue Eigenschaft hinzuzufügen Foo, also wenn ich es Fooals ViewModel benutzte Auch der Client erhält eine neue Eigenschaft. Was soll ich also tun, wenn es sich bei dieser neuen Eigenschaft um ein Sicherheitsfeld handelt (möglicherweise "Wahr / Falsch" für die Erlaubnis oder ähnliches)?
Mehdi Dehghani
@mehdi Sie müssen genauer festlegen, welches Feld Sie hinzufügen möchten und warum es Ihrer Meinung nach in der Ansicht angezeigt wird oder nicht. Oder überhaupt, worum es geht.
Svidgen
@mehdi um klar zu sein, wenn Sie besorgt sind, dass Endbenutzer einen Sicherheitswert ändern, sollte Ihre Domain Benutzern einfach nicht erlauben, Dinge zu speichern, zu deren Speichern sie nicht berechtigt sind
svidgen
Warum verwenden wir ViewModels? Es gibt einige Gründe, wie wir wissen, einer davon ist für die Sicherheit, zum Beispiel, dass User edit formwir kein IsAdminFeld an den Client übergeben müssen, um dieses Feld sicher zu halten. Entschuldigung für mein schlechtes Englisch.
Mehdi Dehghani
1
Anders ausgedrückt, ich denke, die ursprüngliche Frage ist eine vollständige Frage. Die Frage, die Sie in den Kommentaren hier herausfinden möchten, ist eine weitere vollständige Frage. Und Kommentare sind kein guter Weg, um gute und qualitativ hochwertige Antworten zu erhalten.
Svidgen
2

Ich hätte ein Ansichtsmodell, das nur eine Eigenschaft enthält, eine Foo-Instanz. Auf diese Weise verletzen Sie DRY nicht gemäß einer Definition davon, wenn sich Foo ändert, Ihr Ansichtsmodell die Änderung automatisch sieht und Sie sich von einer direkten Bindung des Ansichtsmodells an das Modell frei lassen.

Wenn die Ansicht morgen etwas anderes als das Foo anzeigen muss, können Sie einfach eine neue Eigenschaft hinzufügen, und die Absicht Ihres Ansichtsmodells ist weiterhin klar, es enthält ein Foo und etwas anderes, das Sie nicht haben eine Mischung von Eigenschaften von Foo mit nicht verwandten anderen Eigenschaften.

Ich würde Ihr Ansichtsmodell nicht als FooViewModel betrachten, sondern als das, was in der Ansicht angezeigt werden soll. Wenn nur ein Foo angezeigt wird, enthält das Ansichtsmodell eine Eigenschaft, ein Foo.

Ich bin mir nicht sicher, ob ich das klar erklärt habe. Wenn nicht, lass es mich wissen und ich versuche es umzudrucken, wenn ich wach bin!

Avrohom Yisroel
quelle
-2

Ich würde sagen, dass die Verwendung FooViewModelauf diese Weise das DRY-Prinzip verletzt. Wenn Sie eine Änderung an vornehmen müssen, müssen FooSie auch eine Änderung an vornehmen FooViewModel. Ich denke, Sie wären besser bedient, Foowenn Sie einfach das Modell für Ihre Ansicht verwenden würden. Ich würde ein Ansichtsmodell in Betracht ziehen, wenn Sie Dinge von Foo und etwas anderes anzeigen müssen. Angenommen, Sie müssen einige Informationen von Foound auch von rendern Bar.

zero_dev
quelle
Sagen Sie mir bitte, wenn ich mich dazu entschlossen habe, ein anderes Feld / eine andere Eigenschaft hinzuzufügen. FooDa ich also auch FooViewModel verwendet habe, muss ich dieses neue Feld auch an die Ansicht übergeben. Ich denke, das ist kein gutes Geschäft ?
Mehdi Dehghani
Ich sehe nichts Falsches daran, dass die Ansicht nur eine Teilmenge der vom Modell bereitgestellten Daten verwendet. Ich denke, das größere Foul ist die Kopplung zwischen Foound FooViewModel. Im Allgemeinen ist es keine gute Idee, mehrere Dateien für eine einzige logische Änderung ändern zu müssen.
zero_dev
Was ist, wenn das hinzugefügte Feld ein Sicherheitsfeld ist, z. B. ein true/falseWert für die Berechtigung oder ähnliches ?
Mehdi Dehghani
Sie müssen solche Felder nicht in der Ansicht selbst verfügbar machen, sollten jedoch sicherstellen, dass der Rest Ihres Codes es dem Benutzer nicht erlaubt, seine Sicherheitsstufe zu ändern, nur für den Fall, dass ein böswilliger Benutzer versucht, eine solche Änderung zu veröffentlichen.
Graham
Klingt so, als wäre es offen für Massenzuweisungsangriffe
James