• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 16/05/2023

Découpez votre projet en couches applicatives

Maintenant que vous vous êtes familiarisé avec Maven, penchons-nous sur l'organisation de votre projet.

Du simple patron MVC à une architecture multi-tiers

Le patron MVC

Vous connaissez déjà le patron de conception MVC (Modèle-Vue-Contrôleur). (Si ce n'est pas le cas, vous pouvez vous reporter au cours : Développez des sites web avec Java EE)

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

Pour rappel, avec cette organisation, lorsqu'un utilisateur interagit avec votre application :

  1. son action est prise en charge par le Contrôleur,

  2. qui fait alors appel au Modèle. Celui-ci va réaliser l'action fonctionnelle et éventuellement interagir avec une base de données.

  3. Une fois le travail du Modèle terminé, le Contrôleur met à jour la Vue qui est renvoyée à l'utilisateur.

Améliorer le patron MVC à l'aide du patron DAO

Cette organisation est bien, mais il est possible de l'affiner, en structurant notamment la partie Modèle. En effet, cette partie contient tout le cœur de fonctionnement de l'application, de la logique métier à la gestion des données.

Une manière d'améliorer les choses est d'utiliser par exemple le patron DAO (Data Access Object), permettant de mieux gérer la persistance des données en l'isolant du reste du traitement.

(Si vous ne connaissez pas le patron DAO, vous pouvez vous reporter au cours : Développez des sites web avec Java EE)

Séparer les responsabilités avec une architecture multi-tiers

Je vous propose d'aller plus loin, en adoptant une architecture multi-tiers.

Architecture multi-tiers
Architecture multi-tiers

Avec cette architecture en couches, l'utilisateur interagit avec votre application :

  1. via la couche Présentation. Cette couche contient les parties Contrôleur et Vue du patron MVC.

  2. Une fois l'action utilisateur identifiée, la couche Présentation fait appel à la couche Métier. Celle-ci est responsable de la logique métier de l'application, c'est-à-dire de l'implémentation des règles de gestion fonctionnelles.

  3. Si des accès à la base de données sont nécessaires, alors la couche Métier appelle la couche Persistance. C'est dans cette couche que l'on retrouve le patron DAO.

  4. Et toutes ces couches partagent une « vision commune » du domaine fonctionnel en s'appuyant sur le Modèle. En effet, ce modèle contient les JavaBeans manipulés dans l'application.

Une chose importante est que chaque couche n'appelle que la couche immédiatement en dessous d'elle et n'a aucune connaissance des couches supérieures.

Cette approche présente plusieurs avantages :

  • Imaginez que votre projet comporte une application web et des batches de traitement en masse. Eh bien, vous pouvez créer 2 couches de présentation (une pour l'application web, l'autre pour les batches) et partager les mêmes couches métier, persistance et modèle.

  • Un autre avantage est qu'il est possible de développer et tester les couches séparément en mettant en place des interfaces.

Séparer les couches applicatives avec Maven

Les modules Maven

Vous pouvez matérialiser le découpage de l'architecture multi-tiers grâce à des modules Maven. Chaque couche de l'architecture fait alors l'objet d'un module dédié.

Les modules sont des sortes de « sous-projets » Maven, rattachés à un projet Maven principal (appelé projet parent). Ils fournissent chacun leurs propres livrables et il est possible de créer des dépendances entres eux.

Voici ce que cela peut donner avec notre projet contenant des batches et une application web :

Architecture multi-tiers mise en oeuvre avec des modules Maven
Architecture multi-tiers mise en oeuvre avec des modules Maven

Vous remarquez que j'ai renommé la couche persistance en module consumer. J'ai, en effet, généralisé la responsabilité de cette couche à la consommation de « services » externes, par exemple une base de données ou des webservices.

Ainsi, votre projet Maven principal va devenir un meta-projet, agrégeant des modules. Dans le jargon de Maven, on appelle cela un projet multi-modules.

Les projets multi-modules

Un projet multi-modules est organisé comme ceci :

🗁 projet-x
├── 🗁 module-a
│   ├── 🗎 pom.xml
│   └── 🗁 src
│       ├── 🗁 main
│       │   └── 🗁 java
│       │       └── ...
│       └── ...
├── 🗁 module-b
│   ├── 🗎 pom.xml
│   └── ...
├── 🗎 pom.xml

Les modules sont dans des sous-dossiers dans le répertoire du projet parent.

Ils ont chacun une arborescence classique de projet Maven avec leur propre fichier pom.xml, leur répertoire src/main/java...

Créer un projet multi-modules

Mettons cela en pratique. Nous allons créer un projet de gestion de ticket d'incident. Il contiendra une application web et un jeu de batches.

Créer le squelette d'un projet multi-modules

Pour créer un projet multi-modules :

  1. Commencez par créer le projet parent à l'aide de l'archétype maven-archetype-quickstart :

    mvn archetype:generate \
        -DarchetypeGroupId=org.apache.maven.archetypes \
        -DarchetypeArtifactId=maven-archetype-quickstart \
        -DarchetypeVersion=1.1 \
        -DgroupId=org.exemple.demo \
        -DartifactId=ticket \
        -Dversion=1.0-SNAPSHOT
  2. Allez dans le répertoire du projet qui vient d'être créé :

    cd ticket
  3. Supprimez le répertoire src, il ne sert à rien :

    rm -r ./src
  4. Éditez le fichier pom.xml :

    • Modifiez le packaging du projet. Il faut utiliser le packaging pom au lieu de jar :

      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
          ...
          <groupId>org.exemple.demo</groupId>
          <artifactId>ticket</artifactId>
          <version>1.0-SNAPSHOT</version>
          <packaging>pom</packaging>
          ...
      </project>
    • Supprimez la dépendance vers junit :

      <project>
          ...
          <dependencies>
              <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
              </dependency>
          </dependencies>
          ...
      </project>
  5. Créez ensuite tous les modules (sous-projets Maven) à l'aide d'archétypes :

    • ticket-batch (archétype maven-archetype-quickstart)

    • ticket-webapp (archétype maven-archetype-webapp)

    • ticket-business (archétype maven-archetype-quickstart)

    • ticket-consumer (archétype maven-archetype-quickstart)

    • ticket-model (archétype maven-archetype-quickstart)

    ## module : ticket-batch
    mvn -B archetype:generate \
        -DarchetypeGroupId=org.apache.maven.archetypes \
        -DarchetypeArtifactId=maven-archetype-quickstart \
        -DarchetypeVersion=1.1 \
        -DgroupId=org.exemple.demo \
        -DartifactId=ticket-batch \
        -Dpackage=org.exemple.demo.batch
    
    ## module : ticket-webapp
    ## Remarquez ici l'utilisation de l'archetype "webapp"
    mvn -B archetype:generate \
        -DarchetypeGroupId=org.apache.maven.archetypes \
        -DarchetypeArtifactId=maven-archetype-webapp \
        -DgroupId=org.exemple.demo \
        -DartifactId=ticket-webapp \
        -Dpackage=org.exemple.demo.webapp
    
    ## module : ticket-business
    mvn -B archetype:generate \
        -DarchetypeGroupId=org.apache.maven.archetypes \
        -DarchetypeArtifactId=maven-archetype-quickstart \
        -DarchetypeVersion=1.1 \
        -DgroupId=org.exemple.demo \
        -DartifactId=ticket-business \
        -Dpackage=org.exemple.demo.business
    
    ## module : ticket-consumer
    mvn -B archetype:generate \
        -DarchetypeGroupId=org.apache.maven.archetypes \
        -DarchetypeArtifactId=maven-archetype-quickstart \
        -DarchetypeVersion=1.1 \
        -DgroupId=org.exemple.demo \
        -DartifactId=ticket-consumer \
        -Dpackage=org.exemple.demo.consumer
    
    ## module : ticket-model
    mvn -B archetype:generate \
        -DarchetypeGroupId=org.apache.maven.archetypes \
        -DarchetypeArtifactId=maven-archetype-quickstart \
        -DarchetypeVersion=1.1 \
        -DgroupId=org.exemple.demo \
        -DartifactId=ticket-model \
        -Dpackage=org.exemple.demo.model

Une fois ceci fait, le fichier pom.xml du projet parent devrait ressembler à ceci (j'ai ajouté des commentaires pour que cela soit plus lisible) :

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- =============================================================== -->
    <!-- Informations du projet -->
    <!-- =============================================================== -->
    <!-- ===== Informations Maven ===== -->
    <groupId>org.exemple.demo</groupId>
    <artifactId>ticket</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <!-- ===== Informations générales ===== -->
    <name>ticket</name>
    <url>http://maven.apache.org</url>

    <!-- =============================================================== -->
    <!-- Properties -->
    <!-- =============================================================== -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!-- =============================================================== -->
    <!-- Modules -->
    <!-- =============================================================== -->
    <modules>
        <module>ticket-batch</module>
        <module>ticket-webapp</module>
        <module>ticket-business</module>
        <module>ticket-consumer</module>
        <module>ticket-model</module>
    </modules>
</project>
```

Vous remarquez que les modules sont listés dans la balise <modules>.

Définir les dépendances entre les modules

L'arborescence de votre projet multi-modules est créée, passons maintenant à la définition des dépendances entre les modules.

Nous le verrons plus en détail dans le chapitre suivant, mais nous allons gérer ces dépendances en deux temps :

  1. Dans le POM du projet parent, nous listerons les dépendances et leur version de manière globale pour le projet.

  2. Dans le POM de chaque module, nous définirons quelles sont les dépendances à utiliser.

Dans le POM du projet parent

Ouvrez le POM du projet parent et ajoutez-y une section dependencyManagement :

<project>
    ...
    <!-- =============================================================== -->
    <!-- Gestion des dépendances -->
    <!-- =============================================================== -->
    <dependencyManagement>
        <dependencies>
            <!-- ===== Modules ===== -->
            <dependency>
                <groupId>org.exemple.demo</groupId>
                <artifactId>ticket-batch</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.exemple.demo</groupId>
                <artifactId>ticket-webapp</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.exemple.demo</groupId>
                <artifactId>ticket-business</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.exemple.demo</groupId>
                <artifactId>ticket-consumer</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.exemple.demo</groupId>
                <artifactId>ticket-model</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>

            <!-- ===== Bibliothèques tierces ===== -->
            ...
        </dependencies>
    </dependencyManagement>
    ...
</project>
Dans les POM des modules

Il ne vous reste plus qu'à définir les dépendances à utiliser dans les POM des modules dans la section dependencies.

Les dépendances à définir sont celles-ci :

Dépendances entre les modules
Dépendances entre les modules

Commençons, par exemple, avec le module ticket-business. Il faut ajouter les dépendances vers les modules :

  • ticket-consumer

  • ticket-model

Ouvrez le POM du module ticket-business ajoutez-y les dépendances suivantes :

<project>
    ...
    <!-- =============================================================== -->
    <!-- Dépendances -->
    <!-- =============================================================== -->
    <dependencies>
        <!-- ===== Modules ===== -->
        <dependency>
            <groupId>org.exemple.demo</groupId>
            <artifactId>ticket-consumer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.exemple.demo</groupId>
            <artifactId>ticket-model</artifactId>
        </dependency>

        <!-- ===== Bibliothèques tierces ===== -->
        <!-- JUnit -->
        ...
    </dependencies>
    ...
</project>

Il ne vous reste plus qu'à procéder de même pour les autres modules.

Après cela, votre projet est prêt, vous pouvez commencer les développements, en répartissant les différents éléments dans leurs couches respectives. ;-)

Construire un projet multi-modules

La construction d'un projet multi-modules se fait comme pour un projet simple :

  1. Vous vous placez dans le répertoire du projet parent.

  2. Vous lancez vos commandes de build Maven dans ce répertoire. Ceci va lancer le build sur chacun des modules.

Par exemple, pour packager votre projet, faites :

cd /chemin/vers/projet-multi-modules
mvn package

Ceci va générer les livrables de chaque module dans le repertoire target de chacun de ces modules.

Résumons

Nous avons vu comment structurer votre projet en utilisant une architecture multi-tiers. Dans cette architecture en couches, chaque couche communique avec celle immédiatement inférieure et n'a aucune connaissance des couches supérieures.

Vous avez pu voir qu'il était possible de matérialiser cette organisation dans un projet Maven grâce aux modules.

Et enfin, je vous ai montré comment créer et construire un projet multi-modules.

Votre projet et maintenant bien structuré, les différents éléments le constituant sont clairement identifiés. Afin de terminer son organisation, il ne vous reste plus qu'à gérer les dépendances vers les bibliothèques tierces. C'est justement ce que nous allons voir dans le prochain chapitre.

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