Académique Documents
Professionnel Documents
Culture Documents
Les seuls documents autorisés sont ceux distribués en cours / BE / TP et mis à disposition
sur le site Web du module, ainsi que vos notes personnelles.
Notes en préambule :
— le travail doit se faire individuellement ;
— n’oubliez pas d’indiquer votre nom sur chaque feuille rendue ;
— soyez concis et précis, et justifiez vos réponses par des commentaires appropriés ;
— soyez rigoureux dans la syntaxe Java ;
— veillez à rendre une copie propre et lisible.
CF1 2012–2013
Étude de cas. Le système dont le diagramme de classes est représenté en partie dans la
figure 1 consiste en l’organisation du tri de cubes selon différents critères. Un cube possède
quatre attributs privés : un nom qui est une chaîne de caractères, un poids qui est un double,
un volume qui est un double, et une stratégie qui est une référence sur un objet de type
StratégieDeTri.
Nous utilisons la façon de faire Java (c’est-à-dire un patron d’implantation ou idiome)
pour trier les objets contenus dans un tableau : méthode de classe sort de la classe Arrays. Le
code Java de la figure 3 montre un exemple d’utilisation de la méthode de classe sort de la
classe Arrays qui effectue un tri par ordre croissant. Pour être effective, la méthode sort utilise
la méthode compareTo implantée par la classe des objets à trier. Donc, pour être triable, une
classe doit implanter l’interface Comparable, comme indiqué dans le diagramme de classes de
la figure 1 : l’interface CubeTriable étend l’interface Comparable et la classe Cube implante
l’interface CubeTriable.
Le patron de conception « Stratégie » est représenté dans le diagramme de classes par
la classe abstraite StratégieDeTri et les classes TriAucun, TriParNom, TriParPoids, et TriPar-
Volume. Ce patron de conception utilise le concept d’interface pour permettre de choisir la
stratégie de tri ; chaque classe implantant l’interface réalise une stratégie. Le diagramme de
communication de la figure 2 montre une utilisation de l’algorithme de la méthode de tri
algorithmeDeTri. Après avoir vérifié que l’objet en argument est non null et de type Cube-
Triable, et avoir transformé par un downcast la référence obj en la référence o, la méthode
algorithmeDeTri est appelée.
Les questions suivantes permettent d’implanter le système. Comme montré dans le code
de la méthode main de la classe Main, toutes les classes font partie du paquetage stratégie.
Questions
Question 1 [2 pts] : en étudiant le code de la classe main de la classe Main dans la figure 3,
répondez très succinctement aux questions qui suivent :
1. que signifie le mot-clef static de la méthode main ?
2. pourquoi le mot-clef static est obligatoire pour la méthode display ?
3. combien d’objets de type StratégieDeTri sont créés dans la méthode main ?
4. ré-écrivez l’une des boucles for sous une autre forme.
Réponse:
Réponse:
package strategie ;
public interface CubeTriable extends Comparable < Object > {
public StrategieDeTri g etStrategieD eTri ();
public void setStra tegieD eTri ( StrategieDeTri s );
public String getNom ();
public double getPoids ();
public double getVolume ();
}
Réponse:
package strategie ;
public class Cube implements CubeTriable {
private String nom ;
private double poids ;
private double volume ;
private StrategieDeTri strategie ;
public Cube ( String n , double p , double v , StrategieDeTri s ) {
nom = n ;
poids = p ;
volume = v ;
strategie = s ;
}
public String toString () {
return (" Le cube de nom ‘" + nom + " ’ pese " + poids
+ " kg pour un volume de " + volume + " m3 .");
}
public int compareTo ( Object ob ) {
if ( ob != null ) {
if ( ob instanceof CubeTriable ) {
CubeTriable o = ( CubeTriable ) ob ;
if ( strategie != null ) {
return strategie . algorithmeDeTri ( this , o );
}
}
}
return 0;
}
public StrategieDeTri g etStrategieD eTri () {
return strategie ;
}
public void setStra tegieD eTri ( StrategieDeTri s ) {
strategie = s ;
}
public String getNom () {
return nom ;
}
public double getPoids () {
return poids ;
}
public double getVolume () {
return volume ;
}
}
—
Barème de correction sur 6 point(s) :
Répartition :
2
0,5 public class
0,5 implements CubeTriable
0,5 attributs nom, poids, volume (private et types)
0,5 attribut stratégie (private et type)
2
0,5 prototype constructeur
0,5 corps constructeur
0,5 toString (indices dans la visualisation d’une exécution)
0,5 les getters et le setter
2 compareTo (indices dans le diagramme de communication)
0,5 test null
0,5 test instanceof
0,5 downcast
0,5 return stratégie.algorithmeDeTri
Question 4 [4 pts] : écrivez tout le code de la classe abstraite StratégieDeTri et des classes
TriAucun et TriParNom.
Réponse:
package strategie ;
public abstract class StrategieDeTri {
protected int nbAppelsTotal = 0;
public abstract int algorithmeDeTri ( CubeTriable a , CubeTriable b );
}
package strategie ;
public class TriAucun extends StrategieDeTri {
public int algorithmeDeTri ( CubeTriable a , CubeTriable b ) {
super . nbAppelsTotal ++;
return 0;
}
}
package strategie ;
public class TriParNom extends StrategieDeTri {
public int algorithmeDeTri ( CubeTriable a , CubeTriable b ) {
super . nbAppelsTotal ++;
return a . getNom (). compareTo ( b . getNom ());
}
}
Répartition :
0,5 classe abstraite StratégieDeTri
0,5 méthode abstraite algorithmeDeTri
0,5 attribut nbAppelsTotal protégé et initialisé à 0
0,5 extends StratégieDeTri dans les classes TriAucun et TriParNom
0,5 super.nbAppelsTotal++ dans les classes TriAuncun et TriParNom
0,5 return 0 dans la classe TriAucun
1 return a.getNom().compareTo(b.getNom()) dans la classe TriparNom
0,5 getNom
0,5 compareTo
Réponse:
package strategie ;
public class CubeAvec Except ion implements CubeTriable {
private String nom ;
private double poids ;
private double volume ;
private StrategieDeTri strategie ;
public CubeAve cExcep tion ( String n , double p , double v , StrategieDeTri s ) {
nom = n ;
poids = p ;
volume = v ;
strategie = s ;
}
public String toString () {
return (" Le cube de nom ’" + nom + " ’ pese " + poids
+ " kg pour un volume de " + volume + " m3 .");
}
public int compareTo ( Object ob ) throws ClassCastException {
if ( ob != null ) {
if ( ob instanceof CubeTriable ) {
CubeTriable o = ( CubeTriable ) ob ;
return strategie . algorithmeDeTri ( this , o );
}
throw new ClassC as tException (" pas le bon type ");
}
throw new C la ssCas tE xcepti on (" argument null ");
}
public StrategieDeTri g etStrategieD eTri () {
return strategie ;
}
public void setStra tegieD eTri ( StrategieDeTri s ) {
strategie = s ;
}
public String getNom () {
return nom ;
}
public double getPoids () {
return poids ;
}
Question 6 [2 pts] : écrivez, en utilisant JUnit et en vous inspirant d’une partie du scénario
de la méthode main de la classe Main, un test de validation permettant de tester que
les tris réalisés correspondent au jeu de données d’entrée. Par exemple, quatre cubes
utilisent la stratégie de tri par poids, chaque cube possède un poids différent, et le tri
est correct.
Dans cette question, vous pouvez utiliser la méthode de classe assertEquals de la classe
Assert avec deux arguments de type Object.
Réponse:
package strategie ;
import java . util . Arrays ;
Question 7 [1 pt] : dans la méthode main de la classe Main, observez que rien n’interdit que
d1 utilise la stratégie TriParPoids, et que d2, d3 et d4 utilisent la stratégie TriParNom.
Proposez une solution simple pour éviter le risque d’erreur provenant d’un tri inco-
hérent car différentes stratégies de tris sont utilisées. En d’autres termes, modifiez la
classe Cube pour qu’à un instant donné tous les cubes utilisent la même stratégie de
tri.
Réponse:
Main +algorithmeDeTri(
CubeTriable a, CubeTriable b): int
+main(String[] args)
TriParNom
+display(CubeTriable[] cubes)
Cube
+algorithmeDeTri(
CubeTriable a, CubeTriable b): int
− nom : String
− poids : double
− volume : double TriParPoids
+constructeur(String nom,
double poids, double volume,
+algorithmeDeTri(
StratégieDeTri s) CubeTriable a, CubeTriable b): int
+toString(): String
// liste des autres méthodes
...
TriParVolume
+algorithmeDeTri(
CubeTriable a, CubeTriable b): int
compareTo(obj): int
2:r=algorithmeDeTri(c, o): int [o != null]
:TriParNom c:Cube
2.1:nc=getNom():String
2.2:no=getNom():String
o:Cube
Figure 2 – Diagramme de communication de la méthode compareTo de la classe Cube lorsque le tri est
effectué avec un objet de classe TriParNom.
package strategie ;
import java . util . Arrays ;
public class Main {
public static void main ( String [] arg ) {
CubeTriable d1 = new Cube (" a " , 4.0 , 1.0 , new TriAucun ());
CubeTriable d2 = new Cube (" b " , 3.0 , 3.0 , new TriAucun ());
CubeTriable d3 = new Cube (" c " , 2.0 , 2.0 , new TriAucun ());
CubeTriable d4 = new Cube (" d " , 1.0 , 3.0 , new TriAucun ());
CubeTriable [] cubes = { d1 , d2 , d3 , d4 };
System . out . println (" Liste d ’ origine :");
display ( cubes );
Arrays . sort ( cubes );
System . out . println ();
System . out . println (" Liste des cubes , tri par defaut :");
display ( cubes );
for ( CubeTriable c : cubes ) {
c . setStr ategie DeTri ( new TriParNom ());
}
Arrays . sort ( cubes );
System . out . println ();
System . out . println (" Liste des cubes , tri par nom :");
display ( cubes );
for ( CubeTriable c : cubes ) {
c . setStr ategie DeTri ( new TriParVolume ());
}
Arrays . sort ( cubes );
System . out . println ();
System . out . println (" Liste des cubes , tri par volume :");
display ( cubes );
for ( CubeTriable c : cubes ) {
c . setStr ategie DeTri ( new TriParPoids ());
}
Arrays . sort ( cubes );
System . out . println ();
System . out . println (" Liste des cubes , tri par poids :");
display ( cubes );
}
public static void display ( CubeTriable [] cubes ) {
for ( CubeTriable c : cubes ) {
System . out . println (" " + c );
}
}
}
Liste d’origine:
Le cube de nom ‘a’ pese 4.0kg pour un volume de 1.0m3.
Le cube de nom ‘b’ pese 3.0kg pour un volume de 3.0m3.
Le cube de nom ‘c’ pese 2.0kg pour un volume de 2.0m3.
Le cube de nom ‘d’ pese 1.0kg pour un volume de 3.0m3.