EPSI B3 - Java¶
Cours de 3ième année EPSI Bordeaux : les fondamentaux du langage Java
- Introduction
- Installation
- Compilation & exécution
- La structure fondamentale du langage
- Les types primitifs
- Les opérateurs
- Les structures de contrôle
- Les tableaux
- Une première classe
- Attributs & méthodes
- Cycle de vie d’un objet
- Les packages
- Héritage et composition
- Le polymorphisme
- Les classes abstraites
- La classe Object
- La classe String
- Les exceptions
- Les énumérations
- Les interfaces
- Méthodes et classes génériques
- Les collections
- Les entrées/sorties
- Les dates
- Programmation fonctionnelle et lambdas
- Streams
- Les classes internes
- Les annotations
- Les modules
Liens utiles
- L’API Java
- Documentation Java
Exercices¶
Exercice - Programme simple
Testez le programme Java suivant :
public class PremierProgramme {
public static void main(String[] args) {
String message = "Bonjour";
System.out.println(message);
}
}
Pour fonctionner, ce programme doit se trouver dans un fichier PremierProgramme.java
dans le répertoire des sources du projet.
System.out
représente la sortie standard du programme.
Exercice à rendre - les nombres premiers
On souhaite connaître le nombre de nombres premiers entre 1 et 1000. En mathématique, un nombre premier est un nombre qui n’est divisible que par 1 et lui-même.
Complétez la fichier NombrePremier.java
ci-dessous :
public class NombrePremier {
public static void main(String[] args) {
int nbNombresPremiers = 0;
// TODO Trouver le nombre de nombres premiers entre 1 et 1000
System.out.println(nbNombresPremiers);
}
}
Chapitres de référence :
Exercice à rendre - afficher les nombres premiers
On souhaite afficher les nombres premiers entre 1 et 1000. En mathématique, un nombre premier est un nombre qui n’est divisible que par 1 et lui-même.
Complétez la fichier AffichageNombrePremier.java
ci-dessous :
import java.util.ArrayList;
import java.util.List;
public class AffichageNombrePremier {
public static void main(String[] args) {
// List<Integer> représente une liste d'entiers.
List<Integer> nombresPremiers = new ArrayList<>();
// TODO trouver les nombres premiers entre 1 et 1000 et les ajouter dans la liste.
// L'ajout dans la liste se fait avec la méthode nombresPremiers.add().
for (int i : nombresPremiers) {
System.out.println(i);
}
}
}
Chapitres de référence :
Exercice à rendre - afficher les nombres premiers (version 2)
Reprenez l’exercice précédent. On peut redéfinir un nombre premier comme : un nombre qui n’est pas divisible par un autre nombre premier sauf 1 et lui-même.
Améliorez l’implémentation précédente en utilisant la liste des nombres premiers déjà trouvés pour déterminer si le nombre courant est premier.
Chapitres de référence :
Exercice à rendre - La classe Rectangle
Implémentez une classe Rectangle
. Cette classe doit définir les méthodes
suivantes :
public double getLongueur()
public void setLongueur(double valeur)
public double getLargeur()
public void setLargeur(double valeur)
public double getPerimetre()
public double getAire()
public boolean isCarre()
public void transpose()
Pour rappel, le périmètre d’un rectangle est :
périmètre = (longueur + largeur) x 2
Pour rappel, l’aire d’un rectangle est :
aire = longueur x largeur
Un rectangle est un carré si sa longueur est égale à sa largeur. La méthode
transponse
intervertit la largeur et la longueur.
Un fois implémentée, votre classe doit pouvoir être utilisée dans le programme
DemoRectangle.java
ci-dessous :
public class DemoRectangle {
public static void main(String[] args) {
Rectangle r = new Rectangle();
r.setLargeur(10);
r.setLongueur(20);
System.out.printf("Un rectangle de largeur %.2f et de longueur %.2f\n", r.getLargeur(), r.getLongueur());
System.out.printf("Le perimettre de ce rectangle est %.2f\n", r.getPerimetre());
System.out.printf("L'aire de ce rectangle est %.2f\n", r.getAire());
System.out.println(r.isCarre() ? "Ce rectangle est un carre" : "Ce rectangle n'est pas un carre");
r.transpose();
System.out.printf("Un rectangle de largeur %.2f et de longueur %.2f\n", r.getLargeur(), r.getLongueur());
System.out.printf("Le perimettre de ce rectangle est %.2f\n", r.getPerimetre());
System.out.printf("L'aire de ce rectangle est %.2f\n", r.getAire());
System.out.println(r.isCarre() ? "Ce rectangle est un carre" : "Ce rectangle n'est pas un carre");
r.setLargeur(r.getLongueur());
System.out.printf("Un rectangle de largeur %.2f et de longueur %.2f\n", r.getLargeur(), r.getLongueur());
System.out.printf("Le perimettre de ce rectangle est %.2f\n", r.getPerimetre());
System.out.printf("L'aire de ce rectangle est %.2f\n", r.getAire());
System.out.println(r.isCarre() ? "Ce rectangle est un carre" : "Ce rectangle n'est pas un carre");
}
}
Chapitres de référence :
Exercice à rendre - La classe Phrase
Implémentez la classe Phrase. Cette classe permet de créer une chaîne de caractères en ajoutant des mots qui seront séparés par un séparateur. Par défaut, le séparateur est le caractère espace, mais il peut être changé.
La classe Phrase doit permettre de :
ajouter un mot
ajouter une série de mots (nombre de paramètres variable)
ajouter un mot en le répétant n fois (on indique le mot et le nombre de fois qu’il faut le répéter)
changer le séparateur qui peut être soit une chaîne de caractères soit un seul caractère
la méthode
public String toString()
permet de récupérer la phrase sous la forme d’une chaîne de caractères. Cette chaîne doit être terminée par un point.connaître le nombre de lettres dans la phrase
Le code suivant :
Phrase phrase = new Phrase();
phrase.ajouter("Une");
phrase.ajouter("classe");
phrase.ajouter("pour");
phrase.ajouter("ajouter");
phrase.ajouter("des mots");
phrase.setSeparateur(" et encore ");
phrase.ajouter("des mots", 3);
phrase.setSeparateur(' ');
phrase.ajouter("toujours", "et", "encore");
System.out.println(phrase);
System.out.println(phrase.getNbLettres());
doit produire sur la sortie standard
Une classe pour ajouter des mots et encore des mots et encore des mots et encore des mots toujours et encore.
88
Indication
On ne peut pas parcourir directement une chaîne de caractères, par contre on peut obtenir un tableau de caractères à partir d’une chaîne avec la méthode toCharArray.
String helloWorld = "Hello world!";
for (char c : helloWorld.toCharArray()) {
// ...
}
Pour savoir si un caractère est une lettre, on utilise la méthode static Character.isAlphabetic.
Chapitres de référence :
Exercice à rendre - Le jeu du pendu
On souhaite réaliser un programme en ligne de commande pour jouer au jeu du pendu.
Vous devez implémenter la classe JeuDuPendu
. Elle possède :
un constructeur pour lui passer le mot à trouver
la méthode
proposer
qui attend une lettre (char
) en paramètre et qui retournetrue
si la lettre est présente dans le mot à trouverla méthode
getNbTentativesRestantes
qui indique le nombre de tentatives restantes. Ce nombre diminue chaque fois qu’on propose une lettre qui n’est pas dans le motla méthode
isPartieGagnee
qui indique si on a trouvé toutes les lettres du mot.la méthode
isPartieTerminee
qui indique si la partie est terminée. Une partie est terminée si on a gagné ou s’il ne reste plus de tentative.la méthode
getMotMasque
qui retourne sous forme de chaîne de caractères le mot à trouver. ATTENTION, les lettres non encore trouvées sont remplacées par_
.la méthode
getSolution
qui retourne le mot qu’il faut trouver.
Si votre implémentation est complète, vous pourrez la tester avec la classe
DemoJeuDuPendu
ci-dessous :
import java.util.Scanner;
public class DemoJeuDuPendu {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
JeuDuPendu jeuDuPendu = new JeuDuPendu("feuille");
do {
String motMasque = jeuDuPendu.getMotMasque();
int nbTentativesRestantes = jeuDuPendu.getNbTentativesRestantes();
System.out.printf("Le mot : %s\n", motMasque);
System.out.printf("Proposez une lettre (il reste %d tentatives) : ", nbTentativesRestantes);
String ligne = scanner.nextLine();
if (ligne.length() != 1) {
System.out.println("Vous devez saisir une seule lettre!");
continue;
}
char lettre = ligne.charAt(0);
if (! jeuDuPendu.proposer(lettre)) {
System.out.println("Cette lettre n'est pas présente dans le mot à trouver.");
}
} while(! jeuDuPendu.isPartieTerminee());
if (jeuDuPendu.isPartieGagnee()) {
System.out.println("Bravo, vous avez gagné !");
} else {
System.out.printf("Vous avez perdu. Le mot à trouver était %s.\n", jeuDuPendu.getSolution());
}
}
}
Chapitres de référence :
Exercice bonus à rendre - Les constructeurs pour la classe Phrase
En reprenant la classe Phrase, ajoutez les constructeurs suivants :
// constructeur sans paramètre
Phrase phrase = new Phrase();
phrase.ajouter("Bonjour", "le", "monde");
System.out.println(phrase); // Bonjour le monde.
// constructeur pour indiquer quel caractère fini la phrase
Phrase phraseInterrogative = new Phrase(Phrase.INTERROGATION);
phraseInterrogative.ajouter("Ça", "va");
System.out.println(phraseInterrogative); // Ça va ?
Phrase phraseExclamative = new Phrase(Phrase.EXCLAMATION);
phraseExclamative.ajouter("Oui");
System.out.println(phraseExclamative); // Oui !
Phrase phraseDeclarative = new Phrase(Phrase.DECLARATION);
phraseDeclarative.ajouter("C'est", "bien");
System.out.println(phraseDeclarative); // C'est bien.
// constructeur pour indiquer quel caractère fini la phrase
// et passer un nombre quelconque de mots à la phrase
phrase = new Phrase(Phrase.INTERROGATION, "Et", "ensuite");
System.out.println(phrase); // Et ensuite ?
Ajoutez également des méthodes de classe (méthodes statiques) pour créer directement une Phrase selon son type :
phrase = Phrase.interrogation("Comment", "allez", "vous");
System.out.println(phrase); // Comment allez vous ?
phrase = Phrase.exclamation("Dormez");
System.out.println(phrase); // Dormez !
phrase = Phrase.declaration("Brian", "est", "dans", "la", "cuisine");
System.out.println(phrase); // Brian est dans la cuisine.
Chapitres de référence :
Exercice à rendre - Les constructeurs pour la classe Rectangle
Reprenez la classe Rectangle
et ajoutez les constructeurs suivants :
Un constructeur qui attend la largeur et la longueur en paramètre
Un constructeur qui attend une seule valeur pour créer un carré
Un constructeur qui attend un
Rectangle
en paramètre et qui crée un rectangle avec la même largeur et longueur que celui passé en paramètre.
Testez vos implémentations en ajoutant du code de test dans la classe DemoRectangle
.
Chapitre de référence :
Exercice à rendre - Gestion des formations
On souhaite représenter un système de gestion des formations. Chaque formation est représentée par son nom et la liste des modules qui la composent.
Créez les classes Formation
et ModuleFormation
. Un module de formation
a un nom, une description, un nombre maximum de stagiaires acceptés et une
durée en heures pleines. Une Formation
a la propriété duree
qui correspond à la somme des heures des modules qui la composent et la
propriété nbStagiaires
(minimum du nombre autorisé de stagiaires des modules
qui la composent).
Il existe différents types de module de formation :
le type
Cours
qui dispose d’un numéro de sallele type
Tutoriel
qui est représenté par un lien sur une vidéo en ligne. Il n’y a pas de limite au nombre de stagiaires pouvant suivre un tutoriel. Pour simplifier, vous pouvez considérer que la limite est fixée arbitrairement à 1000 stagiaires.le type
Projet
qui est défini par le nombre de groupes et le nombre maximum de stagiaires dans un groupe. Le nombre de stagiaires maximum est donc le produit du nombre de groupes et du nombre de personnes par groupe.
Par exemple, si la formation Programmer en Java comprend :
Un cours de 20h accueillant 25 stagiaires maximum
Un tutoriel en ligne de 4h
Un projet de 30h avec 4 groupes de 5 personnes (soit 5 x 4 = 20 stagiaires)
Alors la formation Programmer en Java dure 54h et est disponible pour 20 stagiaires au maximum.
Testez votre implémentation avec une classe DemoFormation
contenant
une méthode main
. Vérifiez que vous obtenez bien la durée et
le nombre de stagiaires attendus pour une formation.
Chapitres de référence :
Exercice à rendre - Le rectangle (suite)
Reprenez la classe Rectangle
. On veut pouvoir comparer deux rectangles entre
eux. Deux rectangles sont identiques s’ils ont la même longueur et la même largeur.
Modifiez la classe DemoRectangle
pour tester vos ajouts.
Chapitres de référence :
Exercice à rendre - Figures géométriques (1/3)
On souhaite créer des classes Java qui permettent de représenter et de manipuler des figures géométriques.
Une figure est une représentation abstraite d’une forme géométrique. Parmi les figures géométriques, on distingue :
Le rectangle qui est défini par sa longueur et sa largeur
Le disque qui est défini par son rayon
Pour chaque type de figure, il est possible de connaître son périmètre et son aire.
Pour un rectangle
périmètre = (longueur + largeur) x 2aire = longueur x largeur
Pour un disque
périmètre = 2 x π x rayonaire = π x rayon²
Note
La valeur de π est donnée en Java par la constante Math.PI
Reprenez l’implémentation de la classe Rectangle
et implémentez les
classes Disque
et Figure
. Toutes ces classes doivent déclarer les
méthodes getPerimetre()
et getAire()
.
Créez une classe DemoFiguresGeometrique
avec une méthode main
pour
tester votre implémentation.
Chapitres de référence :
Exercice à rendre - Figures géométriques (2/3)
Reprenez l’exercice précédent et ajoutez la classe FigureComposee
. Cette
classe est une figure qui contient une liste de figures. Son périmètre vaut
la somme des périmètres de toutes ses figures. Son aire vaut la somme des
aires de toutes ses figures.
Implémentez la classe FigureComposee
. Déclarez dans cette classe une méthode
ajouter
pour ajouter une nouvelle figure à cette figure composée.
Modifiez la classe DemoFigureGeometrique
pour tester votre nouvelle classe.
Note
Une FigureComposee
doit aussi pouvoir être composée d’autres
FigureComposee
. Dans les modèles de conception (design patterns),
on appelle ce type de classe un composite. On trouve souvent ce type
de représentation : dans un système de fichiers, un répertoire peut être
représenté comme un type de fichier particulier qui peut contenir des
fichiers ou des répertoires.
Chapitres de référence :
Exercice à rendre - Figures géométriques (3/3)
On veut pouvoir comparer deux objets Figure
entre eux. Deux figures
sont identiques si elles ont le même périmètre et la même aire.
Modifiez la classe DemoFigureGeometrique
pour tester vos ajouts.
Chapitres de référence :
Exercice à rendre - Figures géométriques / les exceptions (1/4)
Modifier les classes Rectangle
et Disque
. Il ne doit pas être possible
de donner une valeur négative pour la longueur, la largeur et le rayon à
la construction des objets et sur les méthodes setter.
Utiliser l’exception IllegalArgumentException pour signaler qu’une valeur négative est interdite. Il s’agit d’un unchecked exception utilisée pour signaler un paramètre invalide.
Chapitre de référence :
Exercice à rendre - Figures géométriques / les exceptions (2/4)
Si ce n’est pas déjà le cas, déclarez une méthode ajouter
dans la classe
FigureComposee
pour ajouter une Figure
dans la figure composée.
Afin d’éviter une relation cyclique, il n’est pas possible d’ajouter
une figure composée à elle-même. Dans ce cas, la méthode ajouter
doit
produire une exception du type FigureInterditeException
.
Créez la classe FigureInterditeException
et modifiez la méthode ajouter
de FigureComposee
pour appliquer cette règle.
Faites évoluer les classes existantes afin qu’elles compilent toujours.
Chapitre de référence :
Exercice à rendre - Figures géométriques / les exceptions (3/4)
Étant donnée le programme suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | package geometrie;
import java.util.Scanner;
public class ApprentissageFiguresGeometriques {
private FigureComposee figure = new FigureComposee();
private Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
new ApprentissageFiguresGeometriques().start();
}
public void start() {
while(afficherMenu()) {
print();
print("Votre nouveau choix");
}
}
private boolean afficherMenu() {
print("1) Ajouter un rectangle");
print("2) Ajouter un disque");
print("3) Afficher le perimetre et l'aire");
print("Autre chiffre pour quitter");
switch (scanner.nextInt()) {
case 1:
creerRectangle();
return true;
case 2:
creerDisque();
return true;
case 3:
afficherPerimetreEtAire();
return true;
default:
print("Au revoir");
return false;
}
}
private void creerRectangle() {
print("Quelle est la largeur du rectangle ?");
double longueur = scanner.nextDouble();
print("Quelle est la longueur du rectangle ?");
double largeur = scanner.nextDouble();
Rectangle r = new Rectangle(largeur, longueur);
figure.ajouter(r);
printf("Rectange de largeur %.04f et de longueur %f", r.getLargeur(), r.getLongueur());
printf("Ce rectangle a un perimetre de %.04f et une aire de %.04f", r.getPerimetre(), r.getAire());
}
private void creerDisque() {
print("Quel est le rayon du disque ?");
double rayon = scanner.nextDouble();
Disque d = new Disque(rayon);
figure.ajouter(d);
printf("Disque de rayon %.04f", d.getRayon());
printf("Ce disque a un perimetre de %.04f et une aire de %.04f", d.getPerimetre(), d.getAire());
}
private void afficherPerimetreEtAire() {
printf("Perimetre total : %.04f", figure.getPerimetre());
printf("Aire totale : %.04f", figure.getAire());
}
private void print() {
System.out.println();
}
private void print(String message) {
System.out.println(message);
}
private void printf(String message, Object ... params) {
System.out.printf(message, params);
System.out.println();
}
}
|
Vous pouvez télécharger directement le fichier
ApprentissageFiguresGeometriques.java
Modifiez ce programme pour qu’il gère les exceptions de type IllegalArgumentException si jamais l’utilisateur saisit une valeur négative pour la longueur, la largeur ou le rayon.
Le programme ne doit pas planter. Il doit indiquer à l’utilisateur qu’il a fait une erreur et lui permettre de continuer à utiliser l’application.
Chapitre de référence :
Exercice bonus - Figures géométriques / les exceptions (4/4)
Pour le programme précédent, si vous saisissez autre chose qu’un nombre, le
programme plante car les méthodes nextInt
et nextDouble
de la classe
Scanner lancent alors une InputMismatchException.
Modifiez le programme précédent pour qu’il gère élégamment les erreurs de saisie de l’utilisateur. Par exemple, il peut signaler que la saisie n’est pas correcte et proposer une nouvelle tentative à l’utilisateur.
Astuce
Attention, lorsqu’un objet de la classe Scanner ne peut pas lire une
donnée qui est au mauvais format, il jette une exception InputMismatchException
et il conserve la valeur saisie dans une zone tampon. Cela signifie
que les appels suivants aux méthodes de Scanner vont relire la même valeur !
Pour vider la zone tampon, il suffit de lire la donnée invalide sous
la forme d’une chaîne de caractère en appelant la méthode next()
:
scanner.next();
Chapitres de référence :
Exercice à rendre - La gestion d’un catalogue (1/3)
On désire mettre en place un outil pour la gestion d’articles dans un catalogue.
Important
L’objectif de cet exercice et des suivants est de vous inciter à réaliser une conception objet d’une application. Il serait sans doute possible de réaliser ces exercices en codant une ou plusieurs méthodes avec des centaines de lignes de code. Mais ce type d’implémentation serait maladroite en Java et surtout absolument pas évolutive.
Essayez de mettre en pratique le principe SOLID de la single responsability : une classe doit avoir une responsabilité unique dans un programme. Pour vous guider, les éléments en gras dans le texte représentent des responsabilités différentes qui devaient très certainement être implémentées dans des classes différentes.
Un catalogue est composé d’un ensemble d’articles. Un article a un code, un titre et une note metascore (nombre entier sur 100). Mais il a aussi des caractéristiques qui dépendent du type de l’article :
un film est un article qui a en plus un réalisateur et une affiche. Pour faire simple, l’affiche du film est représentée par une URI sur le web. Par exemple :
https://static.cotecine.fr/tb/Affiches/450x450/ffffff/LES+7+SAMOURAIS.JPG
Plutôt que de représenter l’adresse de l’affiche sur la forme d’une String, vous pouvez utiliser les classes Java URL ou URI.
une série tv est un article qui a en plus un distributeur et un nombre de saisons.
un jeu vidéo est un article qui a en plus un studio de développement et un niveau dans la classification PEGI : PEGI 3, PEGI 7, PEGI 12, PEGI 16 et PEGI 18. Vous pouvez représenter la classification PEGI avec une énumération en Java (Cf. Les énumérations).
Créez les classes pour représenter ce domaine. Placez ces classes dans le
package catalogue
de votre projet.
Exercice à rendre - La gestion d’un catalogue (2/3)
On souhaite implémenter un module pour charger les données d’un catalogue. Les données seront chargées à partir d’un fichier texte dans un format proche du format CSV.
Attention, nous souhaitons garantir une indépendance de ce module avec les
autres modules que nous pourrions implémenter plus tard. Vous devez donc vous
assurer que la classe responsable de charger le catalogue implémente
l’interface ImporteurCatalogue
:
package catalogue.io;
import java.io.IOException;
import catalogue.Catalogue;
public interface ImporteurCatalogue {
Catalogue importer() throws IOException;
}
Vous pouvez télécharger directement le fichier
ImporteurCatalogue.java
Voici un exemple de fichier à traiter. Chaque ligne représente un article en séparant les informations par un point-virgule. La ligne indique, le code, le titre, la note metascore, le type de l’article (film, serie, jeu) puis les informations spécifiques à chaque type d’article.
F0001;Les sept samouraïs;98;film;Akira Kurosawa;https://static.cotecine.fr/tb/Affiches/450x450/ffffff/LES+7+SAMOURAIS.JPG
S0012;The Strain;70;serie;FX;4
JV010;Mass effect;89;jeu;Bioware;PEGI18
Pour lire un fichier, il existe plusieurs solutions en Java. La solution la moins performantes (mais la plus facile à coder) consiste à appeler la méthode de classe Files.readAllLines. Vous pouvez vous reporter au chapitre Les entrées/sorties pour en savoir plus.
Pour l’analyse d’une ligne, vous pouvez utiliser la méthode split de la classe String pour découper la chaîne de caractères en tableau en utilisant le point-virgule comme séparateur :
String[] colonnes = ligne.split(";");
// La première colonne est accessible part colonnes[0], la seconde
// colonne par colonnes[1], etc.
Écrivez une programme qui demande un chemin de fichier à l’utilisateur pour ensuite charger le catalogue. Si le chargement échoue avec une exception, affichez vos excuses à l’utilisateur ainsi que le message de l’exception.
Exercice à rendre - La gestion d’un catalogue (3/3)
On souhaite implémenter un module pour exporter le catalogue au format HTML.
Pour l’exemple de catalogue donné à l’exercice précédent, le résultat de l’export HTML sera :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Catalogue</title>
</head>
<body>
<h1>Catalogue</h1>
<article>
<h2>Les sept samouraïs</h2>
<p>Un film de Akira Kurosawa (metascore : 98)</p>
<img src="https://static.cotecine.fr/tb/Affiches/450x450/ffffff/LES+7+SAMOURAIS.JPG" alt="affiche">
</article>
<article>
<h2>The Strain</h2>
<p>Une série FX en 4 saisons (metascore : 70)</p>
</article>
<article>
<h2>Mass effect</h2>
<p>Un jeu vidéo de Bioware (PEGI-18 et metascore : 89)</p>
</article>
</body>
</html>
Attention, nous souhaitons garantir une indépendance du module d’export.
Vous devez donc vous assurer que la classe responsable d’exporter le catalogue
au format HTML implémente l’interface ExporteurCatalogue
:
package catalogue.io;
import java.io.IOException;
import catalogue.Catalogue;
public interface ExporteurCatalogue {
void exporter(Catalogue catalogue) throws IOException;
}
Vous pouvez télécharger directement le fichier
ExporteurCatalogue.java
L’export consiste à écrire le début du fichier HTML puis, pour chaque article
d’écrire une balise <article>
avec les informations de l’article et enfin,
écrire la fin du fichier HTML.
Nous ne pouvons pas inclure une méthode toHTML
dans notre classe Article
ou une de ces sous-classes pour réaliser l’écriture de la balise <article>
.
Cela ne serait pas conforme au principe de single responsability. Nous ne
pouvons pas non plus nous contenter de coder la procédure d’export dans une
seule méthode : ce code ne serait pas très évolutif.
Pour réaliser l’export, vous devrez créer une interface ExporteurArticle
.
Cette interface sera implémentée par trois classes spécialisées : une pour l’export
de film, une pour l’export de série et une pour l’export de jeu.
Créez également une classe ExporteurArticleFabrique
. Cette classe
agira comme une fabrique.
Note
Une fabrique est un modèle de conception (design patterns) couramment utilisé dans la programmation orientée objet. Il s’agit d’une classe dont la responsabilité est de créer des objets sans que le reste de l’application ne connaisse le type exact des objets créés.
Pour en savoir plus, vous pouvez consulter l’article Wikipedia dédié à ce modèle de conception :
https://fr.wikipedia.org/wiki/Fabrique_(patron_de_conception)
L’architecture générale de l’export peut être schématisée de la manière suivante :
Ce schéma n’est pas complet, par exemple, il manque certainement des méthodes. À vous de vous inspirer de ce schéma pour développer le module d’export.
Écrivez un programme qui demande à l’utilisateur d’indiquer le chemin d’un fichier de catalogue à charger et le chemin d’un fichier HTML à produire. Le programme doit alors charger le catalogue et produire le fichier HTML d’export.