Factorisation par agrégation avec délégation - Retour sur les entiers naturels
Table of Contents
Session 3 - Travaux pratiques - 15 juin 2015 - 13h30-16h15 - 2h45
- Première partie : à préparer à l'avance (temps de travail : trente minutes).
- Seconde partie : TP noté (la seconde partie du sujet sera fournie en début de séance).
Ce TP a pour but de réaliser des factorisations, en utilisant
- des interfaces,
- des fabriques,
- la technique d'agrégation avec délégation.
Le point de départ est formé de quatre classes représentant des entiers naturels. Elles représentent les quatre combinaisons possibles suivant deux axes de variation, la représentation de l'état d'une part, le mode de calcul d'autre part.
Calcul | |||
---|---|---|---|
Via des int | Récursif | ||
Etat | Int positif | NatParIntCalculantAvecDesInts | NatParIntCalculantRecursivement |
Inductif |
NatInductifCalculantAvecDesInts | NatInductifCalculantRecursivement |
Ces classes comportent des redondances et n'utilisent aucune interface ni aucune fabrique. Le but du TP est de les récrire de manière à réaliser progressivement des factorisations, jusqu'à obtenir une solution idéale (sans redondance) recourant à l'agrégation avec délégation. Pour récrire ces classes, on procédera ainsi :
- ajout d'interfaces,
- ajout de fabriques,
- factorisation de la délégation.
Le point de départ : quatre classes d'implémentation
On peut considérer que toute classe possède une structure en deux couches :
- l'état,
- les services, implémentés en utilisant l'état.
Généralement, l'état est représenté par plusieurs attributs. Quant aux services, ils sont implémentés en appelant les accesseurs associés aux attributs et (directement ou indirectement via des fabriques) des constructeurs initialisant les attributs. Voyons le cas qui nous intéresse, celui des entiers naturels, pour lequel on peut distinguer les couches suivantes.
- Couche basse
- Etat représenté par un int ou par le n-ième successeur de zéro
- Accesseurs associés
- Couche haute
- Opérateurs algébriques : les opérations somme et produit, et leurs éléments neutres zero et un, implémentés de différentes manières
Afin de faciliter le développement de la solution par agrégation avec délégation, il est utile d'abstraire l'état par une classe afin d'implémenter les accesseurs par une simple délégation. Ainsi l'état des quatre classes est formé d'un seul attribut, comme nous allons le voir dans les descriptions suivantes.
Deux classes enveloppes d'un int positif
Les classes NatParIntCalculantAvecDesInts et NatParIntCalculantRecursivement utilisent un attribut de type EtatNatParInt. Elles implémentent la couche basse en déléguant à l'attribut et la couche haute de deux manières, respectivement en calculant avec des int et en calculant récursivement. La classe EtatNatParInt représente l'état d'un entier naturel par un int positif, et implémente la couche basse. On obtient ainsi le schéma suivant de classes.
Deux enveloppes d'un int positif
Deux classes avec un état inductif
Les classes NatInductifCalculantAvecDesInts et NatInductifCalculantRecursivement utilisent un attribut de type EtatNatInductif, une classe abstraite. Elles implémentent la couche basse en déléguant à l'attribut et la couche haute de deux manières, respectivement en calculant avec des int et en calculant récursivement. La classe abstraite EtatNatInductif possède deux sous-classes concrètes, EtatZero représentant zéro et EtatSucc représentant tout successeur d'un entier naturel : on retrouve la définition habituelle par induction (ou par récurrence) des entiers naturels.
On obtient ainsi le schéma suivant de classes.
Deux classes avec une définition inductive de l'état
Première partie : travail préparatoire
Créer un projet, importer une archive
- Récupérer l'archive de code.
- La sauvegarder au format zip (donc sans la désarchiver).
- Créer un nouveau projet Eclipse NomPrenom_TP3, où Nom est votre nom et Prenom votre prénom.
- Importer l'archive de code à la racine du projet.
- Projet > Clic droit > Import > Archive File > Next
- From Archive File : …/tp3_fourni.zip > src sélectionné > Into Folder NomPrenom_TP3 > Finish
- Etudier les différentes classes du paquet tp3.fourni en vous aidant des schémas précédents. Déterminer pour chacune les attributs, les constructeurs, les accesseurs et les services.
- Particulièrement, étudier les factorisations possibles, en faisant abstraction des classes d'implémentation utilisées.
- Tester en utilisant la classe tp3.fourni.Test
- Pour terminer, lire et retenir les consignes suivantes concernant l'utilisation d'Eclipse.
Consignes pour une bonne utilisation d'Eclipse
Pour ce TP, quelques consignes doivent être suivies : elles réduisent les possibilités d'erreur.
- Ne jamais suivre les corrections proposées par Eclipse ("quick fix"). En revanche, lire les messages d'erreur.
- Ne rien importer (par une instruction import). Noter que la copie de code réalise des importations silencieuses.
- Ne pas copier de code à l'intérieur d'une classe d'un paquet à un autre. A la place, copier la classe en entier : voir ci-dessous la procédure.
- Les classes ou les interfaces référencées dans une unité de compilation (un fichier) appartiennent toujours au même paquet, ce qui rend inutile toute importation, à l'exception de deux interfaces fournies qu'on référencera en utilisant leur nom complet : tp3.FabriqueNaturels et hierarchie.SemiAnneauUnitaire.
- Pour copier une unité de compilation C (un fichier définissant une
interface ou une classe) d'un paquet X à un paquet Y,
- sélectionner dans le "package explorer" l'unité X.C,
- la copier ("ctrl-C" ou "clic droit > Copy"),
- sélectionner le paquet cible Y,
- coller l'unité ("ctrl-V" ou "clic droit > Paste").
- Remarque : les raccourcis pour copier-coller peuvent changer d'un système à l'autre.
- Eclipse permet de renommer toutes les occurrences d'une entité,
conformément aux règles syntaxiques. Pour renommer :
- clic droit sur le nom > Refactor > Rename,
- Enter new name, press Enter to refactor (au niveau du nom sélectionné).