L'approche mvc : modéle vue controleurs

L'approche mvc : modèle vue contrôleurs

Introduction

Suite à quelques entretiens en SI, question récurrente et « limite » réductrice : Quels sont les 5 fondements de la programmation objet. Le polymorphisme, héritage, encapsulation .etc. et blabla.

En réalité, au delà de la programmation objet la méthodologie utilisée et l'architecture à mettre en place est tout aussi importante - on peut faire du spaghetti même avec .NET ou JAVA full orienté objet . et oui !

Pour ceux qui ne connaissent pas déjà je vous propose de voir l'approche MVC.

Définition

Déjà on ne parle pas de méthodologie ou technique ou bien techno MVC mais d'approche car le modèle MVC peut être constitué d'un ensemble de méthodologies, technos ou techniques.

Le mot MVC vient de MODEL - VIEW - CONTROLER ou en français Modèle - Vue - Contrôleur.

Le Modèle

C'est la représentation de chaque entité du SI. Quelques exemples : classe utilisateur, panier, facture.

La vue

C'est la représentation de l'IHM (interfaces visuelles). Fini le code spaghetti, ici on fait juste de l'affichage, aucun traitement ou définition. Exemple : afficher la liste des utilisateurs.

Le contrôleur

C'est la partie permettant de joindre le modèle et la vue. Effectue l'ensemble des actions demandées par la vue sur le modèle. Exemple : ajouter ou supprimer un utilisateur.

PRINCIPE

Le principe en développement (dans toutes les approches) c'est diviser pour mieux régner. Un exemple de la vie pratique :

Vous êtes fan de photos, vous en faites des tonnes à chaque occasion ! Les mettez-vous dans le même répertoire ? Ou encore mieux, parmi votre dossier vacances 2007 pour rechercher une photo avec votre chien la retrouverez-vous plus facilement en créant des catégories ou des sous-répertoires ou en stockant le tout dans un même dossier ?

La logique de la programmation objet est totalement similaire avec l'avantage en plus de retrouver votre code mais aussi de le rendre réutilisable.

Mais tout cela vous le savez déjà, et ce n'est pas l'approche MVC qui amène cette théorie d'atomisation. Mais entre la théorie et la pratique, lorsqu'on fait du développement IHM on perd vite les bonnes habitudes.

Voilà pourquoi l'approche MVC synthétise le tout sous 3 niveaux simplistes :

Faites des classes pour représenter votre système d'informations, faites des classes effectuant les manipulations de données (LECTURE / ECRITURE), utiliser une méthode permettant seulement d'afficher vos interfaces.

LE MODELE

Votre programme gère des machins ? Dans ce cas définissez chacun de ces machins sous la forme de classes, avec toutes les actions possibles qu'on peut faire dessus.

En plus de gagner un précieux temps lors des mises à jour de votre système, vos machins pourront facilement être étendus et réutilisés.

Du coup, on va aborder la partie mapping, car le plus souvent vos machins vous les stockez dans une base de données.

De manière simplifiée, le mapping consiste à encapsuler la structure de votre base de données et des actions possibles sur chaque entité. Quelques exemples : pdoMap ou jDAO.

Une autre chose, si vous n'utilisez pas d'outil de mapping, utilisez au moins la couche ADO afin d'optimiser l'interopérabilité de votre code ainsi que son éventuelle migration de SGBD.

LE CONTROLEUR

Dans le contrôleur on ne doit pas y voir d'affichage ou de parties reliées à la structure directe des données. Un exemple sous PHP :

Evitez les trucs du genre : echo '<code html>..</machin chose>' ; ou bien $data = mysql_query('SELECT * FROM MA_TABLE..') ; ou comme on peut le voir souvent :

if ($_GET['delete']) mysql_query('DELET FROM MA_TABLE WHERE INDICE = '.$_GET['delete']);

Après avoir vu ce qu'il ne faut pas faire, je vous propose de voir ce qu'il faudrait faire. Dans votre SI votre interface doit pouvoir interagir avec votre SI, en MVC cela donne, les vues doivent interagir avec le modèle, et c'est la le rôle du contrôleur.

Du coup, dans le contrôleur vous pouvez instancier des objets, utiliser des fonctions à travers des structures conditionnelles.

Mais attention, il y a un HIC. Tout SI repose sur des règles métier car on ne développe pas pour des pommes mais bien pour des clients ayant des besoins très très spécifiques. Du coup le mieux serait de créer une classe métier spécialisée dans le traitement de votre modèle.

Si vous avez une dizaine de if imbriqués, et qu'une simple action dans le contrôleur fait interagir trop d'éléments variables, demandez-vous si ce ne serait pas mieux de créer une classe permettant de gérer ces différents cas de figures.

Pour résumer, le contrôleur doit contenir des instructions simples, idéalement des instanciations d'objets, avec des appels de méthodes. Un enfant de 10 ans devrais être capable de lire votre code sans avoir de notions d'algorithmie.

Exemple :

$pomme = new pomme() ;
$pomme->laver() ;
$pomme->croquer() ;
$pomme->jeter() ;

Ça c'est pour la partie traitements, mais comme vous savez il y a globalement une très grosse partie lecture de données.

Dans cette partie le contrôleur ne va qu'instancier les données et surement pas effectuer l'affichage. C'est la vue qui s'en chargera.

LA VUE

La vue est souvent représentée par un système de templating.

Les templates

Juste un petit sondage, qui pense que Smarty est excellent pour faire du MVC ?

Si oui, merci de répondre à cette question :

A quoi ça sert de séparer l'affichage et le code si on utilise un pseudo langage conditionnel ?
Le but est de permettre à un designer d'intervenir sur l'affichage HTML, et non de le former à la syntaxe Smarty. Sinon il sera plus gagnant à apprendre le PHP directement.

Je n'ai pas trouvé pour le moment de système de templating plus performant ou plus complet que le PHP lui-même. J'ai néanmoins une préférence pour des solutions XML -

http://sourceforge.net/projects/dotview/ (solution que je suis entrain de développer)
http://www.pradosoft.com/

Pour cette partie, c'est à vous de trouver ce qui vous convient. Je ne peux que dépeindre ce qui peut être logique et efficace pour moi.

Donc, à par tout ça - normes contraignantes et syntaxe complexe - partons du fait que le designer fait un effort et veut apprendre quelques bases du PHP (echo + boucles foreach) - voyons le MVC avec de simples includes.

Le principe

Votre contrôleur effectue le chargement de données, et doit les transmettre à la vue. On peut tout simplement utiliser $GLOBALS[...] = new machin() ;

Le développeur fera son boulot en disposant les infos de machin dans un tableau par exemple. A lui d'utiliser < ?php echo $GLOBALS[...]->getNom() ; ?> par exemple.

Mais il manque une partie vous me direz, le chargement de la page, ou le système d'encapsulation permettant d'englober le design.

Le router

Dans votre système, vous effectuez un chargement de la couche système (framework) puis vous devez indiquer quel contrôler et vue charger.

C'est le rôle du router, un objet prenant en compte les variables systèmes et effectuant le chargement du contrôler ainsi que son interfaçage avec la vue.

Dans notre exemple, imaginons que vous avez une variable $_GET['page'] et que vous êtes au courant des failles de sécurités dues aux inclusions dynamiques.

Votre router chargera alors le contrôleur correspondant au chemin indiqué par $_GET['page'], puis effectuera l'affichage de la vue associée.

C'est assez synthétique en ce qui concerne l'exécution, par contre nous n'avons toujours pas vu l'encapsulation de l'interface.

L'interface

Vous aimez les include('header.phtml') et include('footer.phml') ?
Ben moi non, ceci pour la simple raison que lorsqu'une balise dans le header est oubliée, ou dans le footer, amusez-vous à debugger le HTML pendant des heures.
Une autre raison, sous DreamWeaver ou autre logiciel, passez en mode design, vous n'aurez aucun aperçu.

Utilisons plutôt le router afin de lui définir quelques fonctions de chargement, puis créons quelques notions manquantes en PHP.

1- Le master

Le design global de votre site, son architecture sera nommée le master ou plus communément le template.

A l'intérieur pas d'affichage et communication avec le contrôleur, seulement avec le router. On pourra y définir des zones dynamiques, ou bien l'emplacement prévu pour la page.

2 - Les WebControls

Parties indépendantes disposant d'une partie effectuant le chargement des données et d'une autre effectuant l'affichage. C'est les emplacements dynamiques des templates.

3 - La page

La page effectue l'affichage des données, et sera pré-bufférisée par le router puis restituée à l'emplacement prévu lors de l'exécution du master.

Donc conclusion, à vous de faire votre architecture de template - mais attention à ne pas réinventer la roue. Si la charge de travail est estimée à plus d'1j/h prenez un système de templating car vos besoins sont trop complexes.

Quelques préconisations

Vous l'avez peut-être déjà remarqué, c'est finit le temps où on faisait 10 tableaux imbriqués et on mettait des spacer.gif à tout va.

Aujourd'hui tout va vers la normalisation, et en matière IHM ce qui est préconisé, c'est l'affichage XHTML représentant les données des pages et le CSS pour ce qui est de la disposition et habillage de la page.

Allez courage, une couche de plus.

A voir également
Ce document intitulé « L'approche mvc : modéle vue controleurs » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous