MVVM, DDD et WPF Layered Application Project Structure Guidance

17

J'essaie de configurer la structure de mon application dans VS et je veux "essayer" et la pérenniser à un niveau raisonnable. Cette application sera une réécriture WPF d'une ancienne application Winform qui n'avait suivi aucune convention. Pas de couches, niveaux, acronymes, etc ...

Il s'agit d'une application d'entreprise assez volumineuse. J'avais prévu d'utiliser Linq To SQL comme mes bases de données sont et seront très probablement toujours MS SQL. J'ai également un ensemble de compétences existant avec lui.

Je veux suivre MVVM et DDD du mieux que je peux, mais je suis confus sur la structure de mon application lorsque je les combine. Permettez-moi d'essayer d'illustrer avec quelques exemples.

Lorsque je suis MVVM, ma structure de dossiers peut ressembler à ceci:

Views
Models
ViewModels
Helpers

mais comment cela s'inscrit-il dans une approche en couches DDD simpliste où ma structure de projet pourrait ressembler à ceci:

MyApp.UI
MyApp.Domain
MyApp.Data

Dois-je mettre le Modelsdans la couche Domaine ou ai-je 3 versions de say Person? Cela conduit à une autre question de savoir où placer mon référentiel et les mappages d'objet DB sur un objet de domaine? Je suppose que Data ...

ViewsJ'irais irais dans l'interface utilisateur mais le ferais ViewModelsaussi?

Enfin, où pourrais-je intégrer ma logique métier?

J'ai trouvé ce qui suit sur CodePlex, Exemple DDD , et cela a été une aide, mais semble être pour une application Web, bien que cela n'ait pas d'importance et que mon ignorance transparaisse.

Ne vous méprenez pas, je sais que je peux avoir autant de dossiers et les appeler comme je veux. J'essaie de comprendre où placer les choses pour que cela soit évolutif, et non pas comment ces endroits sont nécessairement appelés.

Le cœur de ma question pourrait être montré comme ceci.
J'ai un tblPersonobjet généré par *.dbml. Ceci est évident et appartiendrait à ma couche "Données".
Maintenant, j'aurais un modèle, un DTO, un modèle de domaine, ou quelque chose comme ça dans une couche (projet?) Séparée appelée Person. Je aurais besoin d' un Mapperpour Personà tblPersonce que je ne suis pas sûr où mettre.
Ensuite, j'aurai un ViewModel pour, disons, EditPersonqui aurait ses propres propriétés dont il tire Personmais peut-être plus aussi.
Enfin, j'aurais une vue liée à ce ViewModel ....

Pour être clair, ce paragraphe est REMPLI de mes hypothèses et de mes suppositions et j'espère que quelqu'un m'aidera à clarifier l'air ou à y offrir des idées afin que dans 6 mois à un an, je ne me donne pas plus de coups de pied que je n'en ai besoin.

Paladin réfracté
la source
Linq To SQL n'est pas adapté aux grands projets. Utilisez Entity Framework ou un autre ORM comme nHibernate. En outre, cette application est-elle uniquement cliente ou client-serveur?
Euphoric
Il s'agit d'une application WPF Client uniquement. Pourriez-vous également expliquer pourquoi vous pensez que L2S n'est pas adapté à une application de taille moyenne ou plus grande lorsque ma seule source de données est MS SQL?
Paladin réfracté

Réponses:

5

MVVM est un modèle d'interface utilisateur et est utilisé dans un client.

Les parties du domaine en DDD qui sont utilisées dans le client sont probablement (une partie de) le modèle

View et ViewModel sont uniquement client.

J'ai placé des référentiels dans (ou à proximité) du modèle car ils synchronisent le modèle avec le back-end.

Oui, cela entraînera plusieurs fois plusieurs classes Person dans différents espaces de noms. Ils peuvent commencer très similaires mais peuvent finir très différents après quelques itérations ou versions.

ÉDITER

Pour clarifier la partie sur les référentiels et pour en savoir plus sur le positionnement de Business Logic

Si vous créez un système qui contient un client distinct et des référentiels côté serveur / back-end peuvent être utilisés sur le client et le serveur. Dans le client pour fournir une abstraction du ou des serveurs et dans le serveur pour fournir une abstraction d'autres serveurs et sources de données. Ce n'est qu'un modèle.

En ce qui concerne les règles métier: si vous les utilisez dans le client, assurez-vous de les appliquer également sur le serveur. Ne faites jamais confiance à un client. Les règles métier du client permettent une validation rapide des entrées et empêchent les allers-retours vers le serveur.

Je pense que DDD appartient au côté serveur et «fuit» au client.

Euh non
la source
2

Vous avez la bonne direction dans le choix du modèle de conception MVVM pour l'application WPF.

Do I put the Models in the Domain layer?

Oui, vos modèles peuvent être placés dans le domaine

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

Vos référentiels peuvent être placés dans la couche où votre domaine est placé. Vos objets de mappage (également appelés DTO - objets de transfert de domaine) doivent être placés dans votre couche de service et vous pouvez utiliser un puissant outil de mappage AutoMapper pour mapper facilement vos objets de domaine aux DTO.

ViewModels also?

Vos ViewModels doivent être placés sur votre côté client (couche). Vous pouvez construire vos modèles de vue à partir d'un ou plusieurs DTO, selon vos vues.

En ce qui concerne DDD , je suggérerais de lire à ce sujet et de clarifier que vous avez vraiment besoin d'un modèle de conception piloté par domaine. voici une discussion selon laquelle 95% de toutes les applications logicielles entrent dans les catégories «pas si bon pour utiliser DDD».

Edit: la référence a été ajoutée ci-dessus, et merci pour @Den!

Yusubov
la source
s'il vous plaît, commentez lors du vote.
Yusubov
1
Les fanboys DDD veulent l'utiliser partout. Lien connexe: stackoverflow.com/questions/810606/is-ddd-a-waste-of-time
Den
@Den, merci pour le lien! je comptais le chercher.
Yusubov
1

Avant de nous plonger dans ce qui va où, parlons de ce que chaque couche devrait faire.

Le point de vente de MVVM est la liaison entre la vue et le modèle de vue. Le but ici est d'éliminer la logique dans la vue.
Comme la vue, le modèle doit être assez léger et utilisé uniquement pour accéder aux informations (données) nécessaires au fonctionnement du modèle de vue. Le modèle peut combiner l'accès à différentes sources de données, mais il ne doit pas avoir de logique métier. Dans la plupart des cas, vous disposez d'un seul magasin de données à atteindre. Dans certains cas, non. Dans le cas contraire, il convient d'utiliser le modèle pour masquer la source des données de la machine virtuelle.

Un point implicite de MVVM est que les données sont déjà stockées et que votre projet n'est pas responsable du maintien de son organisation. Certains projets ont la chance de s'en tirer avec cette hypothèse, la plupart des projets sur lesquels j'ai travaillé n'ont pas été aussi chanceux. Il suffit de dire que les données sont une autre couche avec laquelle nous devrons faire face.

Je présenterais mon projet comme ceci:

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

et cette couche peut être ajoutée au besoin:

 project.Helpers

Je sépare les Helpers du reste de la pile afin qu'il ne soit pas confondu comme étant une couche de votre pile d'applications.

Avertissement: je ne suis pas un expert DDD, mais je comprends l'essentiel et je vois la valeur de l'approche.

Votre domaine sera le problème que vous envisagez.
Les modèles de domaine vont correspondre principalement aux ViewModels que vous créez; un peu dans les vues; et un petit morceau dans le Model / DataStructs.

Alors, comment ça va se passer?
SI vous avez la possibilité de modifier les structures de données existantes, les nouvelles que vous créez doivent correspondre au problème que vous essayez de résoudre. Vous avez un objet client? Ensuite, vous devriez avoir un / quelques tableaux liés au client. Vous avez des factures ou des produits? Même histoire: des tables et des structures qui correspondent à ces objets métier doivent être créées.

Le domaine sera exprimé à travers vos objets ViewModel et les vues que vous présentez de ces objets. Si vous devez modifier les enregistrements client, vous disposerez d'une machine virtuelle pour gérer cette tâche.

Passons à vos questions:

  1. N'essayez pas de superposer DDD sur MVVM. Ça ne va pas marcher. DDD n'est pas un modèle de disposition, c'est une approche pour visualiser votre problème global.
  2. Le référentiel et les mappages vivront dans project.Data ou project.Model selon le cas.
  3. N'ayez pas de couche appelée UI, sauf si c'est ce que vous voulez appeler project.Views.
  4. Business Logic ira dans le View-Model.

la source
1
D'accord, certaines questions, probablement ignorantes, font suite. (1) feriez-vous de chacun de ces projets un projet séparé ou simplement des dossiers (par exemple Project.View etc.)? (2) DataStructs est l'endroit où vous mettriez les fichiers * .dbml ou Project.Data? (3) Donc, à votre avis, je n'aurais pas de Project.Domain? J'ai vu que utilisé plusieurs fois c'est pourquoi je demande.
Paladin réfracté
@RefractedPaladin - 1) juste des dossiers dans le projet. Vous pourriez faire valoir que Data devrait être son propre projet. Du point de vue de la maintenance, l'une ou l'autre façon est équivalente. 2) oui, exactement. 3) non, je n'aurais pas de dossier .Domain. OMI, notre travail consiste à mapper l'application au domaine de problème commercial. Ainsi, le domaine imprègne toutes les couches du projet.