IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Dotnet Discussion :

Questions d'architecture autour de EDM et WPF


Sujet :

Dotnet

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Par défaut Questions d'architecture autour de EDM et WPF
    Bonjour à tous,

    je vous propose de discuter des différentes possibilités d'implémentation d'une application métier dont l'architecture repose sur les technos suivantes :

    • EDM pour l'accès aux données, leur encapsulation sous forme objets métiers et leur persistance.
    • WPF pour la conception de l'UI.

    Je propose que chacun pose les problèmes qui l'intéresse et le débat portera sur les différentes solutions envisageables (et les possibilités de consensus mais là faut pas trop en demander ).

    PS : je rappelle qu'on parle uniquement d'appli métier basée sur EDM + WPF

  2. #2
    Membre émérite
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Par défaut
    Alors je commence avec une première problématique essentielle : le pattern utilisé pour la séparation des couches.

    Perso, je suis séduit par le motif dit "MVVM", tel que présenté par Josh Smith ici. Cependant comme on peut le lire sur son blog, Josh n'est pas un adepte de l'EDM.

    Quel modèle conviendrait donc pour le design des classes de la couche ViewModel en lien avec des objets EDM ?

    Josh crée une classe de base implémentant INotifyPropertyChanged et destinée à servir de wrapper aux objets métiers. Dans le cas de classes issues de l'EDM, on pourrait peut-être appliquer un pattern de composition (au lieu de wrapper) et exposer par exemple directement une instance métier comme propriété en lecture seule. C'est une possibilité car elle évite de créer un wrapper et les classes métiers EDM implémentent déjà INotifyPropertyChanged. À discuter...

    Quoiqu'il en soit d'une manière plus générale, je trouve que le pattern MVVM impose de fournir deux catégories de services dans les classes ViewModel :
    1. UIProvider : exposer à la couche métier des accesseurs en lecture/écriture aux données métiers (via des propriétés CLR) et une notification de modification (via l'interface INotifyPropertyChanged).
    2. DataAdapter : exposer des services de chargement et persistance des données métier.

    Je vais ici me concentrer sur la partie "UIProvider" : une partie des services UIProvider est fournie avec le wrapper ou la composition exposant les propriétés de l'objet métier (soit directement soit via son instance).
    Mais il demeure une autre partie : assurer à la couche UI la notification des changements pour lesquels l'événement INotifyPropertyChanged.PropertyChanged ne suffit pas.

    Ce cas de figure se présente par exemple lorsqu'on travaille avec des vues de collections filtrées, triées ou regroupées. Par conséquent, pour obtenir une mise à jour de l’affichage de la vue sans provoquer une itération systématique sur tous les éléments de la collection sous-jacente, il est possible de déclencher l’événement CollectionChanged de la collection sous-jacente (en supposant qu'elle implémente INotifyCollectionChanged). Voici là une piste sur le "comment". Mais la difficulté provient plutôt du "quand" effectuer cette notification.

    Perso, je trouverais dommage de devoir souscrire à l'événement Propertychanged de toutes les instances d'objets métiers en cours pour détecter tout changement susceptible d'impacter une vue affichant l'instance modifiée. Je pense qu'il serait plus pertinent de ne "surveiller" que les instances réellement susceptibles d'être modifiées. On pourrait les appeler instances "actives" ou "sélectionées" (peu importe). L'idée, c'est que dans l'UI on ne peut modifier manuellement qu'un nombre limité d'élément à la fois (strictement parlant, un seul car pour en mofifier plusieurs à partir d'une action utilisateur il faut du code et donc la procédure de mise à jour dispose alors en général de moyens supplémentaires pour faire connaître ses changements contrairement à la seule infrastructure WPF agissant à partir d'éléments définis en pur xaml). Donc mieux vaudrait tracer uniquement cet élément "actif", "sélectionné" ou "édité". Là plusieurs possibilités existent... Avec code-behind, uniquement en xaml, etc.

    Qu'en pensez-vous ?

    Fred is back !

  3. #3
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Perso, j'ai commencé à regarder MVVM et je le trouve très intéressant, surtout car il permet vraiment d'être faiblement couplé ce qui facilite grandement les tests unitaires.

    Après, je n'ai pas trop regardé EDM donc je ne sais pas ce que cela vaut avec ce pattern mais je vais essayer de creuser ca....

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Perso, je suis séduit par le motif dit "MVVM", tel que présenté par Josh Smith ici.
    Ah oui, j'ai lu cet article il y a 2 jours, vraiment pas mal du tout...

    Par "EDM" tu veux parler d'Entity Framework je suppose ?

    J'ai déjà fait un petit projet perso utilisant Entity Framework et WPF, et j'avais rencontré pas mal de soucis sur le binding, que j'avais contournés par des moyens plus ou moins élégants... (bon, ok, c'était carrément crade )

    Mais à l'époque où j'ai développé ça je ne connaissais pas MVVM, et je pense que ça devrait changer la donne... Tout ce que j'ai lu à ce sujet me donne assez envie de reprendre mon projet en appliquant le pattern MVVM, faudrait juste que je trouve un peu de temps pour m'y remettre

    Par contre j'ai pas bien compris ce qui te pose problème par rapport aux notifications de modifs...

  5. #5
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Par défaut
    Quels avantages de MVVM sur MVP ?

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par anthyme Voir le message
    Quels avantages de MVVM sur MVP ?
    Justement Josh Smith en parle dans son article
    http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

    Contrairement à MVP, MVVM a été conçu spécifiquement pour WPF, en tenant compte des possibilités de WPF (binding, commandes, ICollectionView...)

    Pour moi, le principal avantage est que grâce au binding, le ViewModel n'a aucune référence vers la vue, et la vue n'a aucune référence statique vers le ViewModel... donc tu peux facilement les interchanger, tester le ViewModel indépendemment de la vue, etc...

  7. #7
    Membre émérite
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Par défaut
    Pour ma part, j'ai découvert le MVVM et notamment l'article de Josh grâce au blog de thomas.

    Citation Envoyé par tomlev
    Par "EDM" tu veux parler d'Entity Framework je suppose ?
    Ouaip !

    Citation Envoyé par tomlev
    Par contre j'ai pas bien compris ce qui te pose problème par rapport aux notifications de modifs...
    En effet je pense que je pinaille un peu sur cette question. J'ai poussé le perfectionnisme un peu loin, peut-être jusqu'à une voie sans issue (ce serait pas la première fois).
    En général, j'ai une phobie pour les abonnements intempestifs aux événements et pour les boucles à répétition sur les collections...
    En l'occurence, je vais expliciter un peu de manière à profiter aux mieux de vos avis mais aussi pour aborder éventuellement une autre problématique...

    Nous savons que INotifyPropertyChanged permet à l'UI WPF de rester synchro avec les modifications des données. De même pour l'interface INotifyCollectionChanged qui permet aux vues de rester synchro lors des opérations classiques sur les collections (ajout, suppression, etc.).

    Toutefois j'ai remarqué dans le cas des vues que INotifyPropertyChanged ne suffit pas à une vue pour mettre à jour son tri, son filtrage ou ses groupes. Ceci est problématique lorsque le tri, filtre ou regroupement est basé sur la propriété qui a été modifiée. Maintenant là où je chipotais un peu, c'est pour les solutions à ce problème.

    Je vais vous faire part de mes tests et de la solution que j'envisage actuellement.

    Après tests (sur des vues ListCollectionView et ItemCollection), j'ai remarqué que la méthode Refresh d'une vue ne permet pas de mettre à jour le tri, le filtrage ou les groupes.
    Par contre il suffit de déclencher artificiellement l'événement CollectionChanged de la collection source pour obtenir que la vue dans WPF se mette à jour correctement. J'écarte la solution de redéfinir le filtre de la vue car cela oblige à créer du code-behind, cela ne concerne a priori que le filtre, et enfin cela oblige à passer en revue tous les items de la collections source un par un (l'une de mes phobies ) avec les critères du filtre.

    Donc ma solution : faire ce que faisait déjà Josh Smith, c'est à dire inscrire un gestionnaire pour l'événement PropertyChanged de chaque Item ajouté à la collection. Cela se passe dans l'objet ViewModel qui expose la collection. Lui le faisait pour surveiller les items sélectionnés dans l'UI (et faire un calcul dessus), moi j'en aurai besoin pour déclencher artificiellement l'événement CollectionChanged si je sais que cette collection est triée, filtrée ou regroupée dans l'UI.

    Pour déclencher l'événement artificiellement, je déplace dans la collection l'item modifié (par exemple avec la méthode ObservableCollection.Move).

    Voilà. Maintenant, l'optimisation que j'essayais d'obtenir était la suivante : ne pas inscrire de gestionnaire systématiquement lorsqu'un item est ajouté à la collection, mais ne le faire que lorsqu'un item est sélectionné dans l'UI (ou avant qu'il ne soit modifié par code). Car après tout, il est vrai que je n'ai besoin de surveiller les changements que de l'item actuellement sélectionné, vu que pour le modifier il faut d'abord le selectionner... J'espère que je suis assez clair.
    Bref, le problème est que cela devient un peu lourd et complexe de mettre en place la détection et la notification de la sélection d'un item dans l'UI (pour ensuite s'abonner si nécessaire à l'événement Propertychanged de l'item sélectionné). Donc on augmente le risque d'erreur ou d'une maintenance plus délicate. Mais cela reste faisable.

    A la limite (et c'est là que surgit l'autre problématique que j'annonçais au début) l'idée de détecter la sélection peut-être justifiée si on ne s'en sert pas uniqument pour le problème de rafraîchissement de vue que je viens d'évoquer.
    L'article de josh fournit un exemple où détecter la sélection d'un item dans l'UI est pertinent (pour calculer dynamiquement le total des ventes que représentent les items sélectionnés).
    Là il peut devenir intéressant de mettre en place un sytème de détection plus poussé, notamment si on veut pouvoir faire la différence entre plusieurs sélection d'un même item au même moment par différents éléments UI. Vous remarquerez au passage que dans la démo de Josh, l'objet qui surveille la sélection de ces items est en singleton. Ce n'est pas un hasard : c'est parce que son concept de sélection tel qu'il l'a implémenté n'est pertinent que pour une seule vue de sa collection. Mais on pourrait avoir besoin de différencier les sélections d'un même item (même instance) dans plusieurs éléments UI. Cela peut se produire surtout quand on essaie de créer des ViewModel le plus déconnectés possible de leur vues (ce qui est le principe des ViewModel...).
    Bon je m'arrête là sur ce sujet car personne ne va lire...

    Citation Envoyé par tomlev
    Pour moi, le principal avantage est que grâce au binding, le ViewModel n'a aucune référence vers la vue, et la vue n'a aucune référence statique vers le ViewModel... donc tu peux facilement les interchanger
    Interchanger, oui, clairement. Mais dans la pratique, même s'il n'y a plus de référence de la vue vers la couche ViewModel (contrairement à la couche Controler du pattern MVC) je crois que le couplage disons "conceptuel" reste assez fort. Il n'y a qu'à voir les exemples discutés au dessus à propos du concept de (multi)sélection d'un item dans l'UI ou de la nécessité (éventuelle) de savoir si une vue est filtrée, triée ou regroupée dans l'UI. Cependant le découplage disons "technique" est réel, et cela permet théoriquement d'interchanger très facilement. A coup sûr en tout cas, ça permet de gagner en lisibilité et donc en maintenance / évolutivité.

  8. #8
    Membre émérite
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Par défaut
    J'attends toujours avec un intérêt vos remarques sur des points évoqués précédement, mais j'aimerais lancer une autre question se rapportant au débat :

    Dans quelle mesure serait-il pertient de fusionner les couches "Model" et "ViewModel" (pour reprendre les termes du pattern MVVM) ?

    Arguments pour :
    1. Possibilité d'implémenter les services ViewModel dans les classes d'entités métier grâce aux classes partielles <Mode PorkyOrNotPorkyThatIsTheQuestion> ou même à l'héritage (la classe implémentant les services type Provider et Adapter pour UI pouvant carrément hériter du type de l'entité métier )/>.
    2. Les classes métier sont générées par un outil en tant que classe partielle. Autrement dit on peut facilement "nettoyer" le modèle ou en générer un autre, ce qui diminue la nécessité de maintenir séparée la couche du modèle, d'autant plus qu'en définitive, le modèle est bien défini séparément, à savoir dans le fichier CSDL (Conceptual Schema Definition Language)
    3. Les classes métier générées implémentent déjà INotifyPropertyChanged et globalement, les services fournit par EDM (type Provider, Adapter, Suivi de modification...) empiètent sur les responsabilités et la raison d'être du ViewModel.
    4. L'exigence de maintenir une couche ViewModel séparée afin de pouvoir la conserver en cas de changement de la couche Model est parfois illusoire. Car il y a un couplage fort à la fois conceptuel et technique (référence statique du ViewModel vers Model).


    Arguments contre :
    1. On est plus dans un motif MVVM à proprement parler
    2. La division et séparation nette des couches permet de gérer des projets (très) lourds et complexes (or qui peut le plus, peut le moins)

  9. #9
    Membre émérite
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Par défaut
    Citation Envoyé par FRED.G Voir le message
    Après tests (sur des vues ListCollectionView et ItemCollection), j'ai remarqué que la méthode Refresh d'une vue ne permet pas de mettre à jour le tri, le filtrage ou les groupes.
    Petite rectification et compléments après vérifications :
    La méthode ItemCollection.Refresh ne rafraîchit rien.
    Par contre, si je récupère la vue avec CollectionViewSource.GetDefaultView la méthode Refresh fonctionne (pour le filtre, tri et regroupement).
    J'ai remarqué aussi que lorsque la sélection change dans la ListBox, l'événement CollectionViewSource.Filter est déclenché pour le nouvel élément sélectionné.

    A part ça pour le fond du débat, n'hésitez pas à partager vos expériences / point de vue. En attendant j'essai de trouver des ressources en anglais sur cette question : quel pattern pour Entity Framework (EDM) + WPF.

Discussions similaires

  1. Question sur Architecture d'un jeu vidéo 3D
    Par Polygon dans le forum Développement 2D, 3D et Jeux
    Réponses: 2
    Dernier message: 28/10/2007, 12h43
  2. [C# 2.0] Question d'architecture - code dynamique
    Par StormimOn dans le forum Framework .NET
    Réponses: 11
    Dernier message: 06/03/2007, 11h19
  3. [Création d'un moteur] Petite question d'architecture technologique
    Par ludovic85 dans le forum Décisions SGBD
    Réponses: 9
    Dernier message: 07/02/2007, 18h00
  4. [Architecture] Question d'architecture
    Par bourbaki2003 dans le forum Général Java
    Réponses: 3
    Dernier message: 11/07/2006, 10h38
  5. [JPanel] [GUI] question d'architecture
    Par _KB_ dans le forum AWT/Swing
    Réponses: 3
    Dernier message: 15/06/2006, 15h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo