Mon premier blog

Aller au contenu | Aller au menu | Aller à la recherche

Tag - Architecture

Fil des billets

jeudi, août 27 2009

MVVM 2.2 - Hiérarchie de base des ViewModels

Tous les ViewModels ont des caractéristiques et des fonctionnalités communes. Dans le but de nous faire gagner du temps et de nous simplifier la vie, une hiérarchie de base est nécessaire. La structure présentée est tirée d'un article de Josh Smith. Dans les fonctionnalités communes, on trouve la notification des propriétés qui peuvent être bindées. Mais aussi la gestion de commandes, de workspaces... 

Les ViewModels sont le coeur de l'architecture. C'est par ces classes que transite toutes les données et toute la logique métier. En effet, les Views ne prennent en charge seulement l'aspect graphique, avec des déclenchements d'animations, des rendus ou encore l'intégration du multimédia. La couche Model quant à elle expose des classes sans logique fonctionnelle. On retrouve cependant dans cette couche, de la logique concernant des conversions de valeurs, ainsi que des validations. Les validations peuvent être soit bindées directement sur les Views via leur ViewModel, soit être utilisées dans une logique fonctionnelle du ViewModel. Un autre point non négligeable dans MVVM est la libération de la mémoire en prenant compte du couplage entre la View et son ViewModel. Dans certaines Views, on pourra laisser la possibilié à l'utilisateur de fermer chacune d'entre elles. Dans ce cas le ViewModel associé devra prendre en charge la libération de la mémoire, ainsi qu'une commande de fermeture. Par rapport à l'architecture de base de Josh Smith, dans son article, j'ai placé une classe dans la hiérarchie qui gère un espace de travail pouvant contenir d'autres espaces de travail. Le conteneur gère les controles de type ItemsControl.

Voici le diagramme de classe qui illustre cette architecture : ViewModelBaseDiagram.png

Il faut savoir que les architectures MVVM peuvent différées selon nos besoins de développement. Lorsque l'on désire poser une telle architecture il est indispensable d'avoir à l'esprit l'ampleur du projet. Pour des petits projets, cette architecture est adéquat, par contre pour des projets plus importants, il existe des frameworks qui exploitent des fonctionnalités très intéressantes comme par exemple le framework Prism, mais l'utilisation d'une telle librairie peut devenir très vite une usine à gaz si l'organisation du projet n'est pas assez verrouillée.

mardi, août 25 2009

MVVM 1.2 - Mise en place de la solution

Dans cet article nous allons voir un exemple d'organisation d'une solution utilisant MVVM. Vous en trouverez surement d'autres, mais j'affectionne particulièrement celle-ci, car elle marque bien la séparation des couches.

On créé tout d'abord un nouveau projet dans File -> New Project ... On choisit une application de type WPF ou bien Sylverlight ou encore Surface...

La solution se génère et nous créée un nouveau projet comportant 2 fichiers : App.xaml et Window1.xaml

  1. On supprime le fichier Window1.xaml
  2. On supprime la propriété StartupUri dans le fichier App.xaml car nous avons supprimé la classe affecté à celle-ci ;)
  3. On crée une nouvelle fenêtre que l'on nomme MainWindow.xaml. Cette classe sera notre fenêtre principale. Elle aura par la suite une classe ViewModel attribuée, que l'on nommera MainWindowViewModel.

Pour attribuer une ViewModel à une View, on affecte la ViewModel à la propriété DataContext de la View. Ce procédé permet d'effectuer la Binding soit OneWay ou TwoWay entre les composants de la View et les propriétés de la ViewModel.

4. Dans le code behind de la classe App, on surcharge la méthode OnStartup(StartupEventArgs e). Cette méthode remplace la propriété StartupUri en code xaml, mais nous permet de coupler la View au ViewModel.

Voici l'implémentation de cette méthode :

MVVM_OnStartup_Mise_en_place.bmp

Ceci étant fait, on va s'occuper des couches. Pour cela on créé 3 nouveaux projets dans la solution de type Librairie de classes, que l'on nomme respectivement Model, View et ViewModel. Pour les assemblies, nous avons besoin de référencer la librairie Model dans celle de ViewModel. Cette référence nous permettra de récupérer les données externes et de pouvoir les rendre accessible par binding aux Views. Nous n'avons pas besoins de référencement entre les couches View et ViewModel. Par contre, on ajoutera les 2 assemblies dans le projet principal afin de pouvoir coupler chaque View avec son propre ViewModel, grâce entre autres aux DataTemple, mais nous y reviendrons dans un prochain articel.

Pour finir afin de garder un couplage net entre les UserControls de la librairie View et leur ViewModel associé, on créé un nouveau répertoire dans le projet ViewModel que l'on nomme ViewModelsList. Ce répertoire, en toute logique comportera autant de fichiers que le projet View et permettra de dédier un namespace propre au couplage. La structure de base de la couche ViewModel, ainsi que le ViewModel associé à la fenêtre principale (MainWindowViewModel.cs) seront stockées à l'extérieur de ce répertoire.

Voila à quoi devrai ressembler votre arborescence :

MVVM_Aborescence_Mise_en_place.bmp

vendredi, août 21 2009

MVVM 1.1 - Qu'est-ce donc cet acronyme ?

En Bref

MVVM ou Model-View-ViewModel est un design pattern qui est apparu pour la nouvelle génération d'interface utilisateur .Net : Windows Presentation Fondation (WPF). Cette architecture permet un découpage en plusieurs couches d'une application. Le gros avantage est que sa structure permet le travail en parallèle du développeur et du designer.

Voici un schéma explicatif : Schéma MVVM

La couche Model

La couche model est la couche la plus simpliste de l'architecture, mais la plus délicate, car chaque classe doit être, en théorie, interopérable. Lorsque vous construisez ces classes, veillez à ce qu'elles puissent être réutilisable dans d'autres applications. Les classes de cette couche peuvent servir dans le pattern comme des contrats qui lient, par exemple, la couche d'accès aux données et la couche ViewModel. Afin d'étoffer ces classes, on pourra si nécessaire faire des validations pour la validation d'attributs. Si on prend l'exemple d'un formulaire basique avec nom, prénom... On aura une classe Person qui devra valider les champs que l'utilisateur renseigne afin de savoir si l'adresse mail est au bon format par exemple. Les classes issuent d'ADO .Net qui mappent les tables d'une base de données, peuvent aisemment faire partie de cette couche.

La couche View

Le rendu graphique d'une application WPF, plus communément appelé la couche View, est complètement désolidarisé du reste des couches. De plus, les rendus graphiques en WPF utilisent le xaml qui est un langage déclaratif. Le designer travaillant, par exemple sur Expression Blend, génère les fichiers xaml correspondants aux vues, en parallèle du développeur qui utilise Visual Studio. Les données seront envoyées et/ou reçues dans le code behind grâce au databinding. Il est fortement déconseillé, et d'ailleurs, c'est le but de ce pattern, de n'avoir aucun code behind dans ces classes. A la limite, juste le constructeur, qui fait appel à la méthode InitilizeComponents() qui charge le code xaml. On ne verra plus d'abonnement à des évènements, bien que cela reste une possibilité de dernier recours. On passera par le binding des commandes suite au clic d'un bouton par exemple. Les commandes ne sont autres que des méthodes anonymes lancées par exemple, à partir d'expressions lambdas.

La couche ViewModel

C'est la couche la plus importante du pattern. Elle est assimilable à la couche Controller, du pattern MVC bien connu. Elle permet de gérer les commandes, ainsi que la notification des propriétés pour le binding aux Views. Il y aura une classe ViewModel attribuée à chaque classe View de créée. Les classes ViewModel sont désignées pour récupérer les données, via la couche d'accès aux données, stockées dans des base de données, des fichiers XML ou encore des flux RSS... La récupération de données est contractée (formatée/Mappée) par les classes de la couche Model. Une classe ViewModel peut afficher de nouvelles Views en instanciant simplement les ViewModels associés. Cette couche demande une hiérarchie de base afin de nous faciliter la tâche et de nous éviter de réecrire 50 fois les mêmes bouts de codes. Nous verrons dans un prochain article cette structure plus en détail. Une fois l'architecture mise en place, le développement s'accélère "Vitesse grand V". En effet, le développeur n'a plus à ce soucier du mécanisme, et peut se concentrer seulement sur les données à binder ou les commandes à déclencher, pendant que le designer prend en charge les Views.