Semaine 10

Activité 1

Approche Modèle-Vue-Contrôleur (MVC)

Sommaire

Introduction

L’approche Modèle-Vue-Contrôleur est une approche de conception de systèmes informatiques permettant de diviser en modules logiques une application comportant des interfaces graphiques, des données et de la logique (c’est-à-dire du contrôle).

L’approche MVC a été introduite dans le langage SmallTalk, un langage de programmation très simple et purement orienté objet. SmallTalk avait pour but de démontrer qu’il était possible d’offrir un langage de programmation simple, mais complet. De plus, SmallTalk a été l’un des premiers langages orientés objet [1].

Ainsi, l’approche MVC divise une application informatique en trois séparations logiques. Les voici.

  1. Modèle – Il s’agit de la composante qui gère les données d’une application (p. ex., la modification ou la création de données). Dans la plupart des applications, le modèle gère les accès aux bases de données dans lesquelles les données sont stockées. Par contre, si le modèle est capable de manipuler les données, il est complètement dissocié de la manière de les présenter aux usagers. Ainsi, le Modèle offre au reste de l’application un ensemble d’objets permettant d’accéder aux données et de les manipuler.
  2. Vue – Il s’agit de la composante permettant d’afficher les données aux utilisateurs selon des modèles de conception  établis par les concepteurs. La Vue a pour seule tâche  d’afficher les données par l’intermédiaire des composantes graphiques (champs de texte, tableaux, etc.) et de récupérer les entrées des utilisateurs par l’intermédiaire de ces mêmes composantes (boutons, champs d’écriture, etc.). Les données affichées proviennent de la composante Modèle et les entrées sont envoyées vers le Contrôleur.
  3. Contrôleur – Il s’agit de la pièce maîtresse de l’architecture MVC. Le Contrôleur connaît les besoins de la Vue et du Modèle et sait quel moyen la Vue utilise pour modifier ou demander des informations au Modèle. Il transforme les requêtes de la Vue en action, ou suite d’actions, compréhensibles par le Modèle et informe la Vue de changements d’état du Modèle. Cette dynamique peut s’exécuter de façon synchrone ou non. Très souvent, la Vue et le Contrôleur forment une paire. [1]

Voici une représentation graphique du modèle MVC et du flux d’information entre les composantes :

 MVC

Avantages de l’utilisation du MVC [1]

1) Plusieurs Vues partagent le même modèle – L’implémentation est donc plus simple puisque les Vues utilisent toutes la même interface avec le Modèle.

2) Plus grande facilité d’adaptation à différentes interfaces – Pour ajouter une interface différente, il suffit d’écrire une autre Vue et un Contrôleur puisqu’il ne faut pas modifier le Modèle.

3) Clarté de la conception – En regardant les différentes méthodes du Modèle, il est facile de comprendre comment l’utiliser; l’écriture d’une ou de plusieurs interfaces est donc grandement facilitée. La maintenance est aussi aisée.

4) Modularité de la conception – On peut modifier plus aisément des éléments du système. Le Modèle peut même subir des modifications sans que cela n’affecte le Contrôleur ou la Vue pour autant qu’il se conforme à l’interface définie. De plus, il est possible de développer le système en parallèle si les interfaces du système sont bien définies.

5) Facilité d’expansion – On peut ajouter d’autres Vues et Contrôleurs ou, encore, enrichir le Modèle si on conserve l’interface existante.

6) Facilité de transformation en applications distribuées – Il est facile de transformer une application en applications distribuées (p. ex., passer d’une application graphique standard [en Java avec l’API Swing] à une application Web).

7) Utilisation possible d’un modèle multiplateforme  – On peut utiliser un Modèle multiplateforme, et les composantes Vue-Contrôleur peuvent être adaptées à la plateforme. On conserve l’apparence native au système d’exploitation et on conserve la logique du programme commune aux différentes plateformes.

 

Exemples de produits utilisant l’approche MVC

1)    Ruby on Rails est un bon exemple de l’utilisation de l’approche MVC dans une plateforme d’applications Web. Ainsi, Ruby on Rails est une plateforme permettant le développement d’applications Web à partir du langage Ruby, où une séparation très marquée entre les trois composantes est directement inscrite dans la mécanique de la plateforme. Par exemple, avec Ruby on Rails, il est possible d’utiliser une base de données SQL et de générer automatiquement la base d’une application Web à partir des schémas de la base de données. Ainsi, pour chaque table, on peut créer un Modèle en Ruby, une Vue permettant d’afficher et de modifier les données du Modèle et un Contrôleur. Les  développeurs peuvent ensuite modifier cette base de code à leur gré. Il existe bien d’autres plateformes utilisant l’approche MVC comme cadre de développement, dont Apache Struts en Java et Django en Python.

 

2)    Cocoa est l’API de Mac OS X permettant le développement d’applications utilisant les composantes et services natifs du système d’exploitation. Cocao utilise une structure MVC rigide séparant les données, des interfaces et du contrôle.

 

 

Utilisation de l’approche MVC avec l’API Swing

 

A priori, l’API Swing de Java n’offre pas les structures permettant d’appliquer le MVC. Il appartient  donc aux programmeurs de bien modulariser leur code. La première règle que les programmeurs doivent appliquer est de séparer la manipulation des données (contrôles et modèles) des classes présentant les vues (p. ex., JFrame ou JPanel) en les intégrant à d’autres classes. Les patrons de conception (que nous verrons dans les prochaines leçons) offrent plusieurs outils permettant d’assurer une bonne modularisation et un couplage faible entre la Vue et les Contrôleurs/Modèles.

 

Pour illustrer l’application du MVC à une interface en Swing, voici deux exemples pas à pas simples.

 

Cas 1 : Développer un formulaire d’inscription à une ligue de soccer.

Pour cet exemple, nous utiliserons l’IDE NetBeans pour créer un projet d’application Java avec le nom « InscriptionSoccer » (ou tout autre nom).

Nous créons ensuite trois classes.

  1. Une classe Joueur, représentant les données des joueurs inscrits; il s’agit du Modèle.
  2. Une classe Formulaire, qui est un JFrame et qui représente le formulaire permettant d’ajouter des joueurs.
  3. Une classe Contrôleur, qui va gérer l’ajout de joueurs à la liste.

 

Donc, les Joueurs seront présentés par une classe qui contiendra les données propres à un joueur (on s’en tient à l’essentiel pour l’exemple) : Nom, âge, numéro de téléphone. La Vue devra manipuler la classe Joueur ainsi que le Contrôleur.

Le Contrôleur implémente une liste de joueurs et une méthode permettant d’ajouter des joueurs à cette liste.

Le formulaire, qui est un JFrame, crée la représentation graphique du formulaire et permet l’entrée de données. Une fois que les donnes sont entrées, elle envoie au Contrôleur les données du joueur à ajouter à la liste.

Voici la vidéo de démonstration :

 

Code source de la solution : inscriptionSoccer

Dans cet exemple simplifié, la Vue ne doit pas afficher des données du modèle.  Nous n’avons donc pas démontré la dépendance entre la Vue et le Modèle. Le second exemple servira à illustrer ce lien.

 

Cas 2 : Transformer un code existant en approche MVC

Voici une application simplifiée permettant de  surveiller l’état d’un moteur industriel à quatre vitesses. Cette application a été mise au point sans tenir compte du modèle MVC (code original :  MoteurIndustriel-sansMVC).  Nous modifierons le code afin de rendre celui-ci compatible avec l’approche MVC. Voici la vidéo de démonstration :

 

 

Voici le code final :

 MoteurIndustriel-avecMVC

Ainsi, le couplage entre les données (Modèle) et la Vue est beaucoup moins fort et peut permettre l’évolution de ces deux concepts de façon relativement indépendante. De plus, vous aurez peut-être remarqué que, pour les besoins de l’exemple, nous avons mis la logique de fonctionnement du moteur dans le Modèle et non dans le Contrôleur. Du point de vue de la programmation orientée objet, il est plus logique d’implémenter le comportement du moteur dans la classe MoteurIndustriel que dans le Contrôleur. Le Contrôleur n’est pas forcément celui qui manipule les données, mais plutôt celui qui contrôle les échanges de données et la suite logique entre l’enchaînement de plusieurs interfaces. Notez également qu’il peut y avoir plusieurs Contrôleurs selon la complexité de l’application.

 

Bibliographie :

  1. Bouchard, F. (2007) IFT515 – Interfaces et multimédia – notes de cours, Sherbrooke (Québec). License Creative Commons