• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Itération 2 : passage à une architecture MVC

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Le but de cette itération est de modifier notre application web d'exemple en introduisant une architecture de type MVC (Modèle-Vue-Contrôleur).

Critique de l'application existante

Les principaux défauts de notre application web actuelle sont les suivants :

  • Elle mélange balises HTML et code PHP.

  • Sa structure est monolithique, ce qui rend sa réutilisation difficile.

De manière très générale, tout logiciel doit gérer plusieurs problématiques :

  • interactions avec l'extérieur, en particulier l'utilisateur : saisie et contrôle de données, affichage. C'est la problématique de présentation ;

  • opérations sur les données (calculs) en rapport avec les règles métier (« business logic »). C'est la problématique des traitements ;

  • accès et stockage des informations qu'il manipule, notamment entre deux utilisations. C'est la problématique des données.

L'application web actuelle mélange code de présentation (les balises HTML) et accès aux données (requêtes SQL). Ceci est contraire au principe de responsabilité unique (Single Responsibility Principle). Ce principe de conception logicielle est le suivant : afin de clarifier l'architecture et de faciliter les évolutions, chaque élément d'une application doit avoir un rôle et une responsabilité unique.

L'architecture actuelle montre ses limites dès que le contexte se complexifie. Le volume de code des pages PHP explose et la maintenabilité devient délicate. Il faut faire mieux.

Séparation des responsabilités

Isolation de l'affichage

Une première amélioration consiste à séparer le code d'accès aux données du code de présentation au sein du fichierindex.php.

<?php
// Data access
$bdd = new PDO('mysql:host=localhost;dbname=microcms;charset=utf8', 'microcms_user', 'secret');
$articles = $bdd->query('select * from t_article order by art_id desc');
?>
<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <link href="microcms.css" rel="stylesheet" />
    <title>MicroCMS - Home</title>
</head>
<body>
    <header>
        <h1>MicroCMS</h1>
    </header>
    <?php foreach ($articles as $article): ?>
        <article>
            <h2><?php echo $article['art_title'] ?></h2>
            <p><?php echo $article['art_content'] ?></p>
        </article>
    <?php endforeach ?>
    <footer class="footer">
        <a href="https://github.com/bpesquet/OC-MicroCMS">MicroCMS</a> is a minimalistic CMS built as a showcase for modern PHP development.
    </footer>
</body>
</html>

Le code est devenu plus lisible, mais les problématiques de présentation et d'accès aux données sont toujours gérées au sein d'un même fichier PHP. En plus de limiter la modularité, ceci est contraire aux bonnes pratiques de développement PHP (norme PSR-1).

On peut aller plus loin dans le découplage en regroupant le code d'affichage précédent dans un fichier dédié nomméview.php.

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <link href="microcms.css" rel="stylesheet" />
    <title>MicroCMS - Home</title>
</head>
<body>
    <header>
        <h1>MicroCMS</h1>
    </header>
    <?php foreach ($articles as $article): ?>
    <article>
        <h2><?php echo $article['art_title'] ?></h2>
        <p><?php echo $article['art_content'] ?></p>
    </article>
    <?php endforeach ?>
    <footer class="footer">
        <a href="https://github.com/bpesquet/OC-MicroCMS">MicroCMS</a> is a minimalistic CMS built as a showcase for modern PHP development.
    </footer>
</body>
</html>

Le fichierindex.php devient alors :

<?php
// Data access
$bdd = new PDO('mysql:host=localhost;dbname=microcms;charset=utf8', 'microcms_user', 'secret');
$articles = $bdd->query('select * from t_article order by art_id desc');

// Data display
require 'view.php';

La fonction PHP require fonctionne de manière similaire à include : elle inclut et exécute le fichier spécifié. En cas d'échec,include ne produit qu'un avertissement alors querequire stoppe l'exécution du fichier source avec une erreur fatale.

Isolation de l'accès aux données

Nous avons amélioré l'architecture de notre application, mais nous pourrions gagner en modularité en isolant le code d'accès aux données dans un fichier PHP dédié. Appelons ce fichiermodel.php.

<?php

// Return all articles
function getArticles() {
    $bdd = new PDO('mysql:host=localhost;dbname=microcms;charset=utf8', 'microcms_user', 'secret');
    $articles = $bdd->query('select * from t_article order by art_id desc');
    return $articles;
}

Dans ce fichier, nous avons déplacé la récupération des articles du CMS à l'intérieur d'une fonction nomméegetArticles.

Le code d'affichage (fichierview.php) ne change pas. Le lien entre accès aux données et présentation est effectué par le fichierindex.php. Ce fichier est maintenant très simple.

<?php

require 'model.php';
$articles = getArticles();
require 'view.php';

Le résultat affiché reste bien entendu identique.

Bilan

Outre les scripts SQL et la feuille de stylemicrocms.css, notre application est maintenant constituée de trois fichiers :

  • model.php (code PHP uniquement) pour l'accès aux données ;

  • view.php (code PHP et balises HTML) pour l'affichage des articles du CMS ;

  • index.php (code PHP uniquement) pour faire le lien entre les deux pages précédentes.

Le code source associé à cette itération est disponible sur une branche du dépôt GitHub.

Cette nouvelle structure est plus complexe, mais les responsabilités de chaque partie sont maintenant claires. En faisant ce travail de refactorisation, nous avons rendu notre exemple conforme à un modèle d'architecture très employé sur le Web : le modèle MVC

Le modèle MVC

Présentation

Le modèle MVC décrit une manière d'architecturer une application informatique en la décomposant en trois sous-parties :

  • la partie Modèle ;

  • la partie Vue ;

  • la partie Contrôleur.

Ce patron de conception(design pattern) a été imaginé à la fin des années 1970 pour le langage Smalltalk afin de bien séparer le code de l'interface graphique de la logique applicative. Il est utilisé dans de très nombreux langages : bibliothèques Swing et Model 2 (JSP) de Java, frameworks PHP, ASP.NET MVC, etc.

Rôles des composants

La partie Modèle d'une architecture MVC encapsule la logique métier ("business logic") ainsi que l'accès aux données. Il peut s'agir d'un ensemble de fonctions (Modèle procédural) ou de classes (Modèle orienté objet).

La partie Vue s'occupe des interactions avec l'utilisateur : présentation, saisie et validation des données.

La partie Contrôleur gère la dynamique de l'application. Elle fait le lien entre l'utilisateur et le reste de l'application.

Interactions entre les composants

Le diagramme ci-dessous résume les relations entre les composants d'une architecture MVC.

Extrait de la documentation du framework Symfony2
Extrait de la documentation du framework Symfony2

La demande de l'utilisateur (exemple : une requête HTTP) est reçue et interprétée par le Contrôleur. Celui-ci utilise les services du Modèle afin de préparer les données à afficher. Ensuite, le Contrôleur fournit ces données à la Vue, qui les présente à l'utilisateur (par exemple sous la forme d'une page HTML).

Avantages et inconvénients

L'architecture MVC offre une séparation claire des responsabilités au sein d'une application, en conformité avec les principes de conception déjà étudiés : responsabilité unique, couplage faible et cohésion forte. Le prix à payer est une augmentation de la complexité de l'architecture.

Dans le cas d'une application web, l'utilisation du modèle MVC permet aux pages HTML (qui constituent la partie Vue) de contenir le moins possible de code serveur, étant donné que le scripting est regroupé dans les deux autres parties de l'application.

Différences avec une architecture en couches

Attention à ne pas employer le terme de "couche" à propos d'une architecture MVC. Dans une architecture en couches, chaque couche ne peut communiquer qu'avec les couches adjacentes. Les parties Modèle, Vue et Contrôleur ne sont donc pas des couches au sens propre du mot.

Exemple de certificat de réussite
Exemple de certificat de réussite