Anleitung zur Strukturierung von MVVM-, DDD- und WPF-Schichtanwendungen


17

Ich versuche, die Struktur meiner Anwendung in VS einzurichten, und ich möchte sie auf ein vernünftiges Maß "testen" und zukunftssicher machen. Diese Anwendung wird eine WPF-Neuschreibung einer alten Winform-Anwendung sein, die keine Konventionen befolgt hat. Keine Ebenen, Ebenen, Akronyme usw.

Es ist eine ziemlich große Unternehmensanwendung. Ich hatte vor, Linq To SQL so zu verwenden, wie es meine Datenbanken sind, und werde höchstwahrscheinlich immer MS SQL sein. Auch ich habe eine vorhandene Fähigkeit, die mit ihr festgelegt wird.

Ich möchte MVVM und DDD so gut ich kann folgen, aber ich bin verwirrt über die Struktur meiner Anwendung, wenn ich diese kombiniere. Lassen Sie mich versuchen, mit einigen Beispielen zu veranschaulichen.

Wenn ich MVVM folge, sieht meine Ordnerstruktur möglicherweise so aus:

Views
Models
ViewModels
Helpers

aber wie passt das zu einem simplen DDD-Ansatz mit mehreren Ebenen, bei dem meine Projektstruktur etwa so aussieht:

MyApp.UI
MyApp.Domain
MyApp.Data

Muss ich das Modelsin die Domain-Ebene legen oder habe ich 3 Versionen von say Person? Dies führt zu einer weiteren Frage, wo ich mein Repository und die Zuordnungen von DB Object zu Domain Object ablegen würde. Ich würde Daten annehmen ...

ViewsIch würde in UI gehen, aber würde ViewModelsauch?

Wo würde ich schließlich meine Geschäftslogik einbetten?

Ich habe Folgendes bei CodePlex, DDD Example , gefunden und es war eine Hilfe, scheint aber für eine Web-App zu sein, obwohl dies möglicherweise keine Rolle spielt und meine Ignoranz durchscheint.

Versteh mich nicht falsch, ich weiß, ich kann so viele Ordner haben und sie anrufen, wie ich will. Ich versuche herauszufinden, wo Dinge platziert werden müssen, damit diese skalierbar sind und nicht, wie diese Orte notwendigerweise genannt werden.

Das Herz meiner Frage könnte so dargestellt werden.
Ich habe ein tblPersonObjekt generiert von *.dbml. Das liegt auf der Hand und würde in meine "Daten" -Schicht gehören.
Jetzt hätte ich Model, DTO, Domain Model oder wie auch immer es heißt in einer separaten Ebene (Projekt?) Genannt Person. Ich würde ein Mapperdafür brauchen Person, tblPersondass ich nicht sicher bin, wo ich es hinstellen soll.
Dann habe ich ein ViewModel für, sagen wir, EditPersondas seine eigenen Eigenschaften hat, von denen es Personaber möglicherweise auch mehr zieht .
Endlich hätte ich eine Ansicht, die an dieses ViewModel gebunden war ...

Um klar zu sein, dass dieser Absatz mit meinen Annahmen und Vermutungen GEFÜLLT ist und ich hoffe, dass jemand mir dabei hilft, die Luft zu reinigen oder mir Einblicke zu bieten, so dass ich mich in 6 Monaten bis zu einem Jahr nicht mehr aufmische, als ich muss.


Linq To SQL eignet sich nicht für größere Projekte. Verwenden Sie entweder Entity Framework oder ein anderes ORM wie nHibernate. Handelt es sich bei dieser Anwendung nur um einen Client oder um einen Client-Server?
Euphoric

Es ist eine reine WPF-Client-Anwendung. Können Sie auch erklären, warum L2S für eine mittelgroße oder größere App ungeeignet ist, wenn meine einzige Datenquelle MS SQL ist?
Refracted Paladin

Antworten:


5

MVVM ist ein UI-Muster und wird in einem Client verwendet.

Die Teile der Domäne in DDD, die im Client verwendet werden, sind wahrscheinlich (ein Teil) des Modells

View und ViewModel sind nur Clients.

Ich habe Repositorys in das Modell (oder in dessen Nähe) eingefügt, weil sie das Modell mit dem Back-End synchronisieren.

Ja, dies führt häufig zu mehreren Personenklassen in verschiedenen Namespaces. Sie könnten sehr ähnlich beginnen, aber nach ein paar Iterationen oder Veröffentlichungen sehr unterschiedlich enden.

BEARBEITEN

Zur Verdeutlichung des Teils über Repositorys und zur Erläuterung der Positionierung von Business Logic

Wenn Sie ein System erstellen, das einen separaten Client enthält, können serverseitige / Back-End-Repositorys auf dem Client und dem Server verwendet werden. Im Client, um eine Abstraktion der Server bereitzustellen, und im Server, um eine Abstraktion anderer Server und Datenquellen bereitzustellen. Es ist nur ein Muster.

Was Geschäftsregeln betrifft: Wenn Sie diese im Client verwenden, stellen Sie sicher, dass Sie sie auch auf dem Server erzwingen. Vertraue niemals einem Kunden. Geschäftsregeln im Client ermöglichen eine schnelle Validierung der Eingaben und verhindern Roundtrips zum Server.

Ich denke, dass DDD auf der Serverseite gehört und zum Klienten "leckt".


2

Sie haben die richtige Richtung bei der Auswahl des MVVM-Entwurfsmusters für die WPF-Anwendung.

Do I put the Models in the Domain layer?

Ja, Ihre Modelle können in eine Domain gestellt werden

Where would I put my Repository and mappings of DB Object to Domain Object?

Ihre Repositorys können in der Ebene platziert werden, in der sich Ihre Domain befindet. Ihre Zuordnungsobjekte (auch als DTOs bezeichnet - Domain Transfer Objects) sollten in Ihrem Service-Layer abgelegt werden, und Sie können ein leistungsstarkes Zuordnungstool AutoMapper verwenden , um Ihre Domain-Objekte auf einfache Weise DTOs zuzuordnen.

ViewModels also?

Ihre ViewModels sollten auf Ihrer Client-Seite (Ebene) platziert werden. Abhängig von Ihren Ansichten können Sie Ihre Ansichtsmodelle aus einem oder mehreren DTOs erstellen.

In Bezug auf DDD würde ich vorschlagen, dies zu lesen und zu klären, dass Sie wirklich ein domänengetriebenes Designmuster benötigen. Hier ist eine Diskussion, die besagt, dass 95% aller Softwareanwendungen in die Kategorien "Nicht so gut für die Verwendung von DDD" fallen.

Bearbeiten: Referenz wurde oben hinzugefügt, und danke für @Den!


Bitte kommentieren Sie, wenn Sie abstimmen.
Yusubov

1
DDD-Fans wollen es überall einsetzen. Zugehöriger Link: stackoverflow.com/questions/810606/is-ddd-a-waste-of-time
Den

@Den, danke für den Link! Ich hatte vor, danach zu suchen.
Yusubov

1

Bevor wir uns mit dem beschäftigen, was wohin geht, besprechen wir, was die einzelnen Ebenen tun sollten.

Das Verkaufsargument von MVVM ist die Bindung zwischen der Ansicht und dem Ansichtsmodell. Ziel ist es, die Logik in der Ansicht zu eliminieren.
Wie das View-Modell sollte auch das Model relativ kompakt sein und nur für den Zugriff auf die Informationen (Daten) verwendet werden, die für den Betrieb des View-Modells erforderlich sind. Das Modell kann den Zugriff auf verschiedene Datenquellen mischen, sollte jedoch keine Geschäftslogik enthalten. In den meisten Fällen müssen Sie einen einzelnen Datenspeicher aufrufen. In einigen Fällen nicht. Wenn dies nicht der Fall ist, sollten Sie das Modell verwenden, um die Datenquelle von der VM zu verdecken.

Ein impliziter Punkt von MVVM ist, dass die Daten bereits gespeichert sind und Ihr Projekt nicht für die Aufrechterhaltung der Organisation verantwortlich ist. Einige Projekte haben das Glück, mit dieser Annahme durchzukommen. Die meisten Projekte, an denen ich gearbeitet habe, waren nicht so glücklich. Es genügt zu sagen, dass Data eine weitere Ebene ist, mit der wir zu kämpfen haben.

Ich würde mein Projekt so auslegen:

 project.Views
 project.ViewModel
 project.Model
 project.DataStructs

und diese Ebene kann nach Bedarf hinzugefügt werden:

 project.Helpers

Ich trenne die Helfer vom Rest des Stapels, damit sie nicht als Ebene Ihres Anwendungsstapels verwechselt werden.

Haftungsausschluss: Ich bin kein DDD-Experte, aber ich verstehe das Wesentliche und sehe den Wert in der Vorgehensweise.

Ihre Domain wird das Problem sein, das Sie in Betracht ziehen.
Die Domänenmodelle entsprechen in erster Linie den von Ihnen erstellten ViewModels. ein bisschen innerhalb der Views; und ein kleiner Teil innerhalb der Model / DataStructs.

Wie soll das denn gehen?
WENN Sie in der Lage sind, die vorhandenen Datenstrukturen zu ändern, sollten die neu erstellten mit dem Problem korrelieren, das Sie lösen möchten. Haben Sie ein Kundenobjekt? Dann sollten Sie eine / einige Tabellen zum Kunden haben. Haben Sie Rechnungen oder Produkte? Gleiche Story - Tabellen und Strukturen, die diesen Geschäftsobjekten zugeordnet sind, sollten erstellt werden.

Die Domain wird durch Ihre ViewModel-Objekte und die von Ihnen präsentierten Ansichten dieser Objekte ausgedrückt. Wenn Sie Kundendatensätze bearbeiten müssen, verfügen Sie über eine VM, um diese Aufgabe zu erledigen.

Auf zu Ihren Fragen:

  1. Versuchen Sie nicht, MVVM mit DDD zu überlagern. Es wird einfach nicht funktionieren. DDD ist kein Layoutmuster, sondern ein Ansatz zum Anzeigen Ihres Gesamtproblems.
  2. Repository und Zuordnungen befinden sich entweder in project.Data oder project.Model.
  3. Verwenden Sie keine Ebene namens UI, es sei denn, Sie möchten project.Views aufrufen.
  4. Business Logic wird in das View-Model aufgenommen.

1
Okay, einige, wahrscheinlich unwissende, gehen den Fragen nach. (1) Würden Sie jedes einzelne Projekt oder nur Ordner (z. B. Project.View usw.) erstellen? (2) In DataStructs würden Sie die * .dbml- oder Project.Data-Dateien ablegen. (3) Also Ihrer Meinung nach hätte ich kein Project.Domain? Ich habe gesehen, dass ein paar Mal verwendet wird, warum ich frage.
Gebrochener Paladin

@ RefractedPaladin - 1) Nur Ordner innerhalb des Projekts. Sie könnten argumentieren, dass Data ein eigenes Projekt sein sollte. Unter dem Gesichtspunkt der Wartung ist jeder Weg gleichwertig. 2) ja genau. 3) Nein, ich hätte keinen .Domain-Ordner. Unsere Aufgabe ist es, die Anwendung der Geschäftsproblemdomäne zuzuordnen. Die Domain durchdringt also alle Ebenen des Projekts.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.