Comment structurer les modules Java avec exports et requires?

Maintenant que notre module zoo.animal.alimentation est solide, nous pouvons commencer à penser à nos autres modules. Comme vous pouvez le voir dans la Figure 12.6, les trois autres modules de notre système dépendent du module zoo.animal.alimentation.

Modules dépendant de zoo.animal.alimentation

Mise à jour du module d’alimentation

Puisque nous allons faire appeler notre code dans le package zoo.animal.alimentation par d’autres modules, nous devons déclarer cette intention dans la déclaration du module.

La directive exports est utilisée pour indiquer qu’un module a l’intention que ces packages soient utilisés par du code Java en dehors du module. Comme vous pourriez vous y attendre, sans directive exports, le module n’est disponible que pour être exécuté depuis la ligne de commande. Dans l’exemple suivant, nous exportons un package :

module zoo.animal.alimentation {
    exports zoo.animal.alimentation;
}

Recompiler et réempaqueter le module mettra à jour le fichier module-info.class à l’intérieur de notre fichier zoo.animal.alimentation.jar. Ce sont les mêmes commandes javac et jar que vous avez exécutées précédemment :

javac -p mods
    -d alimentation
    alimentation/zoo/animal/alimentation/*.java alimentation/module-info.java

jar -cvf mods/zoo.animal.alimentation.jar -C alimentation/ .

Création d’un module de soins

Ensuite, créons le module zoo.animal.soins. Cette fois, nous allons avoir deux packages. Le package zoo.animal.soins.medical aura les classes et méthodes qui sont destinées à être utilisées par d’autres modules. Le package zoo.animal.soins.details ne sera utilisé que par ce module. Il ne sera pas exporté depuis le module. Pensez-y comme à la confidentialité des soins de santé pour les animaux.

La Figure 12.7 montre le contenu de ce module. N’oubliez pas que tous les modules doivent avoir un fichier module-info.java.

Contenu de zoo.animal.soins

Le module contient deux packages et classes de base en plus du fichier module-info.java :

// AnniversaireHippo.java
package zoo.animal.soins.details;
import zoo.animal.alimentation.*;
public class AnniversaireHippo {
    private Tache tache;
}

// Regime.java
package zoo.animal.soins.medical;
public class Regime { }

Cette fois, le fichier module-info.java spécifie trois choses :

module zoo.animal.soins {
    exports zoo.animal.soins.medical;
    requires zoo.animal.alimentation;
}

La ligne 1 spécifie le nom du module. La ligne 2 liste le package que nous exportons pour qu’il puisse être utilisé par d’autres modules. Jusqu’ici, c’est similaire au module zoo.animal.alimentation.

À la ligne 3, nous voyons une nouvelle directive. L’instruction requires spécifie qu’un module est nécessaire. Le module zoo.animal.soins dépend du module zoo.animal.alimentation.

Ensuite, nous devons déterminer la structure de répertoires. Nous allons créer deux packages. Le premier est zoo.animal.soins.details et contient une classe nommée AnniversaireHippo. Le second est zoo.animal.soins.medical, qui contient une classe nommée Regime. Essayez de dessiner la structure de répertoires sur papier ou de la créer sur votre ordinateur. Si vous essayez d’exécuter ces exemples sans utiliser le code en ligne, créez simplement des classes sans variables ou méthodes pour tout sauf les fichiers module-info.java.

Vous avez peut-être remarqué que les packages commencent par le même préfixe que le nom du module. C’est intentionnel. Vous pouvez penser que le nom du module “revendique” le package correspondant et tous ses sous-packages.

Pour réviser, nous compilons et empaquettons maintenant le module :

javac -p mods
    -d soins
    soins/zoo/animal/soins/details/*.java
    soins/zoo/animal/soins/medical/*.java
    soins/module-info.java

Nous compilons les deux packages et le fichier module-info.java. Dans le monde réel, vous utiliserez un outil de build plutôt que de faire cela à la main.

Maintenant que nous avons compilé le code, il est temps de créer le JAR du module :

jar -cvf mods/zoo.animal.soins.jar -C soins/ .

Création du module des présentations

Jusqu’à présent, nous n’avons utilisé qu’une seule instruction exports et requires dans un module. Maintenant, vous allez apprendre à gérer l’exportation de plusieurs packages ou à exiger plusieurs modules. Dans la Figure 12.8, observez que le module zoo.animal.presentations dépend de deux modules : zoo.animal.alimentation et zoo.animal.soins. Cela signifie qu’il doit y avoir deux instructions requires dans le fichier module-info.java.

Dépendances pour zoo.animal.presentations

La Figure 12.9 montre le contenu de ce module. Nous allons exporter les trois packages de ce module.

Contenu de zoo.animal.presentations

Regardons d’abord le fichier module-info.java pour zoo.animal.presentations :

module zoo.animal.presentations {
    exports zoo.animal.presentations.contenu;
    exports zoo.animal.presentations.media;
    exports zoo.animal.presentations.horaire;
    
    requires zoo.animal.alimentation;
    requires zoo.animal.soins;
}

La ligne 1 montre le nom du module. Les lignes 2-4 permettent à d’autres modules de référencer les trois packages. Les lignes 6 et 7 spécifient les deux modules dont ce module dépend.

Puis nous avons les six classes, comme indiqué ici :

// ScriptElephant.java
package zoo.animal.presentations.contenu;
public class ScriptElephant { }

// ScriptOtarie.java
package zoo.animal.presentations.contenu;
public class ScriptOtarie { }

// Annonce.java
package zoo.animal.presentations.media;
public class Annonce {
    public static void main(String[] args) {
        System.out.println("Nous aurons des présentations");
    }
}

// Signalisation.java
package zoo.animal.presentations.media;
public class Signalisation { }

// JourSemaine.java
package zoo.animal.presentations.horaire;
public class JourSemaine { }

// FinDeSemaine.java
package zoo.animal.presentations.horaire;
public class FinDeSemaine {}

Si vous suivez toujours sur votre ordinateur, créez ces classes dans les packages. Voici les commandes pour compiler et construire le module :

javac -p mods
    -d presentations
    presentations/zoo/animal/presentations/contenu/*.java presentations/zoo/animal/presentations/media/*.java
    presentations/zoo/animal/presentations/horaire/*.java presentations/module-info.java

jar -cvf mods/zoo.animal.presentations.jar -C presentations/ .

Création du module du personnel

Notre dernier module est zoo.personnel. La Figure 12.10 montre qu’il n’y a qu’un seul package à l’intérieur. Nous n’exposerons pas ce package en dehors du module.

Contenu de zoo.personnel

Basé sur la Figure 12.11, savez-vous ce qui devrait aller dans le module-info ?

Dépendances pour zoo.personnel

Il y a trois flèches dans la Figure 12.11 pointant de zoo.personnel vers d’autres modules. Elles représentent les trois modules qui sont requis. Puisqu’aucun package ne doit être exposé depuis zoo.personnel, il n’y a pas d’instructions exports. Cela nous donne :

module zoo.personnel {
    requires zoo.animal.alimentation;
    requires zoo.animal.soins;
    requires zoo.animal.presentations;
}

Dans ce module, nous avons une seule classe dans le fichier Emplois.java :

package zoo.personnel;
public class Emplois { }

Pour ceux d’entre vous qui suivent sur votre ordinateur, créez une classe dans le package. Voici les commandes pour compiler et construire le module :

javac -p mods
    -d personnel
    personnel/zoo/personnel/*.java personnel/module-info.java

jar -cvf mods/zoo.personnel.jar -C personnel/ .