Test 1 - Lundi 18 mai - 20 minutes
Table of Contents
Nom : …………………….. - Prénom : ………………………
Les réponses sont à donner directement sur l'énoncé, en complétant les espaces libres en pointillé.
- Le langage de programmation utilisé est Java (version 7).
- Dans la suite, l'expression … (trois points) représente du code supposé connu : elle est suivie d'un commentaire décrivant le code omis.
Nous allons définir un type de données pour des agendas. On considère qu'un agenda est représenté par une liste d'évènements. A cet effet, on suppose qu'une interface Evenement est donnée.
L'interface Agenda
On suppose connues les interfaces génériques suivantes.
interface SemiGroupeAdditif<T> { T somme(T x); } interface MonoideAdditif<T> extends SemiGroupeAdditif<T> { T zero(); } interface GroupeAdditif<T> extends MonoideAdditif<T> { T oppose(); }
Compléter la déclaration de l'interface Agenda de manière à garantir qu'un agenda possède :
- une opération d'addition, réalisant la concaténation des listes sous-jacentes d'évènements,
- un élément neutre, traditionnellement noté zéro, correspondant à une liste vide d'évènements.
interface Agenda ..................................................... { Evenement getPremierEvenement(); Agenda getEvenementsRestants(); Evenement getEvenement(int i); int nombreEvenements(); }
Implémentation inductive des agendas
Pour implémenter l'interface Agenda, on utilise le patron de conception "Composite", qui correspond à la définition inductive suivante : un agenda est soit l'agenda vide, soit un agenda composé d'un premier évènement suivi de l'agenda formé à partir des évènements restants. Voici les indications à suivre pour l'implémentation des deux classes associées à cette définition, AgendaVide et AgendaCompose.
- Les méthodes non définies renvoient une exception de type UnsupportedOperationException.
- La méthode zero renvoie un agenda vide, de type AgendaVide.
- La méthode somme réalise la concaténation des listes sous-jacentes d'évènements.
- Les méthodes somme et toString sont implémentées par récursion sur l'objet cible : le cas de base est traité dans la classe AgendaVide, celui construit dans la classe AgendaCompose.
- Les méthodes déclarées dans l'interface définissent les accesseurs habituels d'une liste.
On commence par la classe AgendaVide représentant un agenda vide. La compléter en suivant les commentaires et les indications ci-dessus.
// Un agenda vide est un agenda. class AgendaVide ...................................................... { @Override public Agenda zero() { .................................................................... } @Override public Agenda somme(Agenda x) { .................................................................... } @Override public Evenement getPremierEvenement() { .................................................................... } @Override public Agenda getEvenementsRestants() { ... // Même code que dans getPremierEvenement. } @Override public Evenement getEvenement(int i) { ... // Même code que dans getPremierEvenement. } @Override public int nombreEvenements() { .................................................................... } @Override public String toString() { // Renvoyer une chaîne vide. .................................................................... } }
On termine par la classe AgendaCompose. La compléter en suivant les commentaires et les indications données au-dessus.
// Un agenda composé est un agenda. class AgendaCompose .................................................. { // Définir l'état formé de trois attributs privés : // - premier évènement, // - agenda formé des évènements restants, // - nombre d'évènements au total. private .............................................................. private .............................................................. private .............................................................. // Définir un constructeur initialisant les attributs. public AgendaCompose(Evenement evenement, Agenda agenda) { .................................................................... .................................................................... .................................................................... } @Override public Agenda zero() { .................................................................... } @Override public Agenda somme(Agenda x) { .................................................................... .................................................................... .................................................................... } @Override public Evenement getPremierEvenement() { .................................................................... } @Override public Agenda getEvenementsRestants() { .................................................................... } @Override public Evenement getEvenement(int i) { // Implémenter la méthode par récursion sur l'argument i // (supposé positif au sens large). .................................................................... .................................................................... .................................................................... .................................................................... } @Override public int nombreEvenements() { .................................................................... } @Override public String toString() { // Renvoyer une chaîne composée du premier évènement et d'une // représentation de l'agenda formé des évènements restants. .................................................................... .................................................................... .................................................................... } }
Test des implémentations
On réalise un test des deux classes d'implémentation. Compléter le code en suivant les commentaires. Pour typer les variables, on utilisera uniquement des interfaces.
private static Evenement evenement(String s) { ... // Fonction renvoyant un évènement de nom s } // Fonction principale public static void ...................................(String[] args) { // Initialiser une variable v avec un agenda vide. ..................................................................... // Initialiser une variable a avec un agenda composé // d'un unique évènement de nom A. ..................................................................... // Initialiser une variable b avec un agenda composé // d'un unique évènement de nom B. ..................................................................... // Initialiser une variable ab par la somme de a et b. ..................................................................... ... // Suite des tests }